我一直在使用Tkinter创建一个应用程序以实例化GUI。我正在尝试使其面向对象,以便可以在其他地方使用该代码,从而使Tkinter易于使用。我遇到的问题是能够使用按钮命令的参数调用复杂的函数。
我已经尝试了尽可能多的按钮学习。我已经阅读并观看了有关将命令绑定到特定的鼠标单击并使用partial传递功能来分解功能的视频。这些选项不适合当前的代码体系结构。我尝试的最后一个想法是使用lambda创建一个临时函数。
def add_button(self, title, command, where, frame):
button = ttk.Button(frame, text=title,command=lambda: command)
button.pack(side=where, fill='both', expand=True)
return button
这是一个用所需的小部件实例化页面的类。
class StartPage(Page):
def __init__(self, container, controller):
super().__init__(container, controller)
title_frame = tk.LabelFrame(self, text='StartPage')
title_frame.pack(side='top')
title = tk.Label(title_frame, text='EPA Engine Report Filing', font=('Helvetica', 16))
title.pack(side='bottom', pady=25)
buttons = {'Quit': quit(), 'Stuff': do_something()}
button_frame = tk.Frame(self)
button_frame.pack(side='top', pady=75)
for button, command in buttons.items():
self.add_button(button, command, 'bottom', button_frame)
我的具体问题是,当for循环遍历StartPage.__init__
中声明为按钮的字典时,“填充”按钮的lambda函数是否会覆盖先前的“退出”按钮的lambda函数吗?在这种情况下,如果我理解lambda,最后创建的按钮将是唯一起作用的按钮。当运行此代码时,什么也不显示。当按钮的功能没有括号时,将显示初始窗口,但按钮不起作用。
非常感谢您的阅读和建议,
答案 0 :(得分:3)
您的代码中有几个问题。
首先,您对lambda
的使用不正确。当您执行lambda: command
时,lambda不会执行任何操作。如果要lambda调用命令,则需要使用括号告诉python执行函数(例如:lambda: command()
)。但是,如果您不传递任何参数,则lambda
本身没有任何作用。您只需将命令直接绑定到按钮即可(例如:command=command
)。
另一个问题是您错误地定义了buttons
。考虑以下代码:
buttons = {'Quit': quit(), 'Stuff': do_something()}
上面的代码在功能上与此相同:
result1 = quit()
result2 = do_something()
buttons = {'Quit': result1, 'Stuff': result2}
在所有情况下,您都需要将 reference 传递给函数。例如,这应该起作用:
buttons = {'Quit': quit, 'Stuff': do_something}
...
def add_button(self, title, command, where, frame):
button = ttk.Button(frame, text=title,command=command)