【问题标题】:Why does my button calls a function before I click on it? [duplicate]为什么我的按钮在我点击之前会调用一个函数? [复制]
【发布时间】:2019-06-17 18:14:06
【问题描述】:

我希望在按下按钮后执行我的功能。但是当我运行程序时,按钮会在我单击它们之前调用所有按钮的函数。当我按下按钮时,在我的输出显示后,所有按钮都不起作用。

程序中的其他按钮都以相同的方式正常工作。

#all the buttons calling the same function buttonEntry(num) with different parameters

button1 = Button(frame_bottom, text="1", width="20", height="6", bg=buttonColor, command=buttonEntry("1"))
button2 = Button(frame_bottom, text="2", width="20", height="6", bg=buttonColor, command=buttonEntry("2"))
button3 = Button(frame_bottom, text="3", width="20", height="6", bg=buttonColor, command=buttonEntry("3"))
button4 = Button(frame_bottom, text="4", width="20", height="6", bg=buttonColor, command=buttonEntry("4"))
button5 = Button(frame_bottom, text="5", width="20", height="6", bg=buttonColor, command=buttonEntry("5"))
button6 = Button(frame_bottom, text="6", width="20", height="6", bg=buttonColor, command=buttonEntry("6"))
button7 = Button(frame_bottom, text="7", width="20", height="6", bg=buttonColor, command=buttonEntry("7"))
button8 = Button(frame_bottom, text="8", width="20", height="6", bg=buttonColor, command=buttonEntry("8"))
button9 = Button(frame_bottom, text="9", width="20", height="6", bg=buttonColor, command=buttonEntry("9"))
button0 = Button(frame_bottom, text="0", width="20", height="6", bg=buttonColor, command=buttonEntry("0"))

#function which doesn't execute when button is pressed
def buttonEntry(num):
    n=num
    print(n)

我希望在按下 button1 时显示 1,在按下 button2 时显示 2,所以,打开。但是当我运行程序时,所有按钮都会同时运行它们的命令并显示如下输出:

1
2
3
4
5
6
7
8
9
0

Process finished with exit code 0

然后按下的按钮不显示任何内容。

【问题讨论】:

    标签: python button tkinter tkinter-entry


    【解决方案1】:

    问题在于您如何为每个按钮设置命令:

    command=buttonEntry("1")
    

    因为buttonEntry是一个函数,所以此时调用它,打印数字并将None分配给命令。

    command 也在这里期待一个可调用的。您需要做的是创建一个工厂来创建返回预期值的函数,然后更新您的Button 设置:

    def buttonEntryFactory(num):
        def buttonEntry():
            print num
        return buttonEntry
    
    button1 = Button(frame_bottom, text="1", width="20", height="6", bg=buttonColor, command=buttonEntryFactory("1"))
    

    现在,当您定义按钮时,它会为其创建一个特定的buttonEntry 函数,并附上正确的值并将该函数分配给command。当您单击按钮时,它将按预期调用该函数。

    总之:command 期望得到一个函数(或可调用)作为参数,所以如果你想为命令添加自定义参数,你需要使用工厂来创建一个包含这些参数的函数里面。 (另一种选择是使用lambda,但我发现工厂方法更简洁)。

    【讨论】:

      【解决方案2】:

      Button 小部件将回调函数作为其最后一个参数,当单击按钮时将调用该回调函数。但是,您传入的是buttonEntry("1"),即None,因为这样调用buttonEntry 函数会将名为n 的局部变量设置为num,然后打印num,但不会返回任何东西,即None

      如果你想让函数在点击按钮时被调用,你需要传递函数本身,而不是结果:

      button1 = Button(frame_bottom, text="1", width="20", height="6", bg=buttonColor, command=buttonEntry)
      

      当然,这样一来,回调就不会知道调用了哪个按钮,因为它们都会调用buttonEntry()。因此,您可以创建一个将被调用的 lambda 函数,而不是直接将函数作为回调提供,该函数然后使用正确的值调用 buttonEntry 函数:

      button1 = Button(frame_bottom, text="1", width="20", height="6", bg=buttonColor, command=lambda: buttonEntry("1"))
      

      阅读更多关于函数、返回值和lambda的信息,如果您想了解更多关于它为什么起作用的信息。

      【讨论】:

        【解决方案3】:

        您实际上并没有将函数作为回调传递,而是传递了返回值。要解决此问题,请在所有内容之前添加 lambda:

        button1 = Button(frame_bottom, text="1", width="20", height="6", bg=buttonColor, command=lambda: buttonEntry("1"))
        button2 = Button(frame_bottom, text="2", width="20", height="6", bg=buttonColor, command=lambda: buttonEntry("2"))
        

        等等。

        【讨论】:

        • 谢谢,没想到这么简单
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-27
        • 1970-01-01
        • 2013-04-18
        • 1970-01-01
        相关资源
        最近更新 更多