使用lambda作为命令时,在函数中创建tkinter按钮是否可以正常运行?

时间:2019-06-24 18:59:52

标签: python tkinter

我一直在使用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,最后创建的按钮将是唯一起作用的按钮。当运行此代码时,什么也不显示。当按钮的功能没有括号时,将显示初始窗口,但按钮不起作用。

非常感谢您的阅读和建议,

1 个答案:

答案 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)