Tkinter dynamically create widgets from button

后端 未结 2 1317
日久生厌
日久生厌 2021-01-29 06:40

I\'m attempting to make a dynamic GUI where clicking a button causes the creation of a new frame that is placed above the button with 3 entry widgets (user options) inside of it

2条回答
  •  野的像风
    2021-01-29 07:09

    The main problem is these four lines of code:

    frameNames[len(frameNames) - 1] = Frame(app)
    frameNames[len(frameNames) - 1].pack()
    ...
    createWidgetButton = Button(app, text="createWidgets", command=createwidgets())
    createWidgetButton.grid(sticky=S)
    

    You are creating both the frame and button as a child of app, but you are using grid for one and pack for the other. You must be consistent with all direct descendants of app - they must all use pack or they must all use grid.

    The second problem is this line:

    frameNames += (str("g"+str(len(frameNames))))  #why does the letter & number get added as seperate elements?
    

    Here, frameNames is a list and you are trying to add it with a string. Adding is not the same as appending. You need to append the new name, or put the new name in a temporary list before adding it.

    frameNames.append(str(...))
    

    The third problem is this line:

    createWidgetButton = Button(app, text="createWidgets", command=createwidgets())
    

    The above is exactly the same as this:

    result = createWidgets()
    createWidgetButton = Button(app, text="createWidgets", command=result)
    

    You must pass a reference to a function, not call the function. Change the line to this (notice the lack of parenthesis after createWidgets):

    createWidgetButton = Button(app, text="createWidgets", command=createwidgets)
    

    Unrelated to the problem, but your code would be much easier to read if you used temporary variables instead of repeating the pattern (str("w"+str(len(widgetNames)-1). As written, your code is almost impossible to read. Also, you don't want to be storing widget names, you need to store the actual widgets themselves.

    And finally, don't do a wildcard import. There is simply no good reason to do it.

    Here is how I would rewrite your code:

    import Tkinter as tk
    
    app = tk.Tk()
    
    frames = []
    widgets = []
    
    def createwidgets():
        global widgetNames
        global frameNames
    
        frame = tk.Frame(app, borderwidth=2, relief="groove")
        frames.append(frame)
    
        frame.pack(side="top", fill="x")
    
        for i in range(3):
            widget = tk.Entry(frame)
            widgets.append(widget)
    
            widget.pack(side="left")
    
    createWidgetButton = tk.Button(app, text="createWidgets", command=createwidgets)
    createWidgetButton.pack(side="bottom", fill="x")
    
    app.mainloop()
    

提交回复
热议问题