Tkinter从按钮动态创建小部件

2024-09-30 05:27:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图制作一个动态的GUI,其中单击一个按钮将创建一个新的框架,该框架位于按钮上方,内部有3个条目小部件(用户选项),我需要能够从3个条目小部件中读取用户输入,并可能对其进行修改。每次按下按钮,都会出现三个新的可调用条目小部件。在

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

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

Tags: 用户框架applen部件错误动态条目
2条回答

这是相对简单的。在

我们可以通过创建一个Frame小部件而不是打包它,用我们需要的填充它,然后让一个Button调用Frame小部件上的包。在

很像下面的:

from tkinter import *

class App:
    def __init__(self, root):
        self.root = root
        self.create = Button(self.root, text="Create", command=self.draw)
        self.create.pack(side="bottom")
        self.frame = Frame(self.root)
        self.entry1 = Entry(self.frame)
        self.entry2 = Entry(self.frame)
        self.entry3 = Entry(self.frame)
        self.entry1.pack()
        self.entry2.pack()
        self.entry3.pack()
        self.submit = Button(self.frame, text="Submit", command=self.command)
        self.submit.pack()
    def draw(self):
        self.frame.pack(side="top")
    def command(self):
        print(self.entry1.get())
        print(self.entry2.get())
        print(self.entry3.get())

root = Tk()
App(root)
root.mainloop()

如果您需要添加多个这样的表单,您可以像下面这样使用匿名函数(lambda)的方法来设置“知道”它们在哪个帧中的“自我感知”按钮:

^{pr2}$

主要问题是这四行代码:

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。在

第二个问题是这条线:

^{pr2}$

这里,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),则代码将更易于阅读。如前所述,您的代码几乎无法阅读。另外,您不想存储widget名称,您需要存储实际的widget本身。在

最后,不要执行通配符导入。根本没有好的理由去做。在

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

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

相关问题 更多 >

    热门问题