Tkinter 从按钮动态创建小部件 [英] Tkinter dynamically create widgets from button

查看:46
本文介绍了Tkinter 从按钮动态创建小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个动态 GUI,点击一个按钮会导致创建一个新框架,该框架放置在按钮上方,其中包含 3 个入口小部件(用户选项),我需要能够阅读来自 3 个条目小部件的用户输入 &可能会改变它们.每次按下按钮时,都会出现三个新的可调用条目小部件.

我知道这是错误的,因为它一直给我错误,但是可以使用类似于列表的东西来动态创建小部件吗?

from Tkinter import *应用程序 = Tk()框架名称 = []小部件名称 = []def createwidgets():全局小部件名称全局框架名称frameNames += (str("g"+str(len(frameNames)))) #为什么字母 &数字被添加为单独的元素?widgetNames += [(str("w"+str(len(widgetNames)-1))),(str("w"+str(len(widgetNames)))),(str("w"+str(len(widgetNames)+1)))]frameNames[len(frameNames) - 1] = Frame(app)frameNames[len(frameNames) - 1].pack()widgetNames[len(widgetNames) - 3] = Entry(frameNames[len(frameNames) - 1])widgetNames[len(widgetNames) - 3].pack()widgetNames[len(widgetNames) - 2] = Entry(frameNames[len(frameNames - )- 1])widgetNames[len(widgetNames) - 2].pack()widgetNames[len(widgetNames) - 1] = Entry(frameNames[len(frameNames) - 1])widgetNames[len(widgetNames) - 1].pack()createWidgetButton = Button(app, text="createWidgets", command=createwidgets())createWidgetButton.grid(sticky=S)app.mainloop()

解决方案

主要问题是这四行代码:

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

您正在将框架和按钮创建为 app 的子项,但是您使用 grid 作为其中之一,使用 pack 作为另一个.你必须与 app 的所有直系后代保持一致——他们必须都使用 pack 或者他们必须都使用 grid.

第二个问题是这一行:

frameNames += (str("g"+str(len(frameNames)))) #为什么字母 &数字被添加为单独的元素?

这里,frameNames 是一个列表,您正试图用一个字符串添加它.添加与附加不同.您需要附加新名称,或将新名称放入临时列表中,然后再添加.

frameNames.append(str(...))

第三个问题是这一行:

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

上面和这个完全一样:

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

您必须将引用传递给函数,而不是调用该函数.将这一行改成这样(注意 createWidgets 后面没有括号):

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

<小时>

与问题无关,但如果您使用临时变量而不是重复模式 (str("w"+str(len(widgetNames)-1).正如所写,您的代码几乎无法阅读.此外,您不想存储小部件名称,您需要存储实际的小部件本身.>

最后,不要进行通配符导入.根本没有充分的理由这样做.

以下是我将如何重写您的代码:

将 Tkinter 导入为 tkapp = tk.Tk()帧 = []小部件 = []def createwidgets():全局小部件名称全局框架名称frame = tk.Frame(app,borderwidth=2,relief="groove")帧.附加(帧)frame.pack(side="top", fill="x")对于范围内的 i (3):小部件 = tk.Entry(frame)小部件.附加(小部件)widget.pack(side="left")createWidgetButton = tk.Button(app, text="createWidgets", command=createwidgets)createWidgetButton.pack(side="bottom", fill="x")app.mainloop()

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, and I need to be able to read the user input from the 3 entry widgets & possibly alter them. Each time the button is pressed, three new callable entry widgets should appear.

I know that this is wrong because it has been giving me errors, but could something similar to the lists be used to create the widgets dynamically?

from Tkinter import *

app = Tk()

frameNames = []
widgetNames = []

def createwidgets():
    global widgetNames
    global frameNames
    frameNames += (str("g"+str(len(frameNames))))  #why does the letter & number get added as seperate elements?
    widgetNames += [(str("w"+str(len(widgetNames)-1))), 
                    (str("w"+str(len(widgetNames)))),    
                    (str("w"+str(len(widgetNames)+1)))]

    frameNames[len(frameNames) - 1] = Frame(app)
    frameNames[len(frameNames) - 1].pack()

    widgetNames[len(widgetNames) - 3] = Entry(frameNames[len(frameNames) - 1])
    widgetNames[len(widgetNames) - 3].pack()
    widgetNames[len(widgetNames) - 2] = Entry(frameNames[len(frameNames - )- 1])
    widgetNames[len(widgetNames) - 2].pack()
    widgetNames[len(widgetNames) - 1] = Entry(frameNames[len(frameNames) - 1])
    widgetNames[len(widgetNames) - 1].pack()

createWidgetButton = Button(app, text="createWidgets", command=createwidgets())
createWidgetButton.grid(sticky=S)

app.mainloop()

解决方案

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()

这篇关于Tkinter 从按钮动态创建小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆