Python 为什么在我单击按钮之前出现测试标签?

Python 为什么在我单击按钮之前出现测试标签?,python,tkinter,tk,Python,Tkinter,Tk,我用tkinter实现了一个python程序,我想在单击按钮后显示fct1的结果。当我运行程序时,即使我没有单击按钮,结果也会显示在窗口中 from tkinter import * def fct1(): u = 0.1 while 1 + u != 1: u /= 10 return u * 10 def create_gui(): window = Tk() window.title("Math") window.geometry('350x200') label1 =

我用tkinter实现了一个python程序,我想在单击按钮后显示fct1的结果。当我运行程序时,即使我没有单击按钮,结果也会显示在窗口中

from tkinter import *

def fct1():
 u = 0.1
 while 1 + u != 1:
  u /= 10
return u * 10

def create_gui():
 window = Tk()
 window.title("Math")
 window.geometry('350x200')
 label1 = Label(text=' ')
 label1.grid(column=2, row=0)
 btn = Button(window, text="Function1", command=clicked(label1))
 btn.grid(column=1, row=0)
 window.mainloop()

def clicked(label1):
 output = fct1()
 label1['text']=str(output)

create_gui()

我认为你应该重构一下你的代码。tkinter GUI最好在全局命名空间或类中使用。也就是说,由于括号的原因,您的命令无法工作。所发生的情况是,在init中只调用一次带括号的命令,因此需要在没有括号的情况下或在lambda函数中调用该命令

清理示例:

import tkinter as tk


def fct1():
    u = 0.1
    while 1 + u != 1:
        u /= 10
    return u * 10


def clicked():
    label1['text'] = fct1()


window = tk.Tk()
window.title("Math")
window.geometry('350x200')
label1 = tk.Label(text=' ')
label1.grid(column=2, row=0)
tk.Button(window, text="Function1", command=clicked).grid(column=1, row=0)
window.mainloop()
最好使用一个类。这样可以避免很多问题:

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Math")
        self.geometry('350x200')
        self.label1 = tk.Label(self, text=' ')
        self.label1.grid(column=2, row=0)
        tk.Button(self, text="Function1", command=self.clicked).grid(column=1, row=0)

    def clicked(self):
        self.label1['text'] = self.fct1()

    def fct1(self):
        u = 0.1
        while 1 + u != 1:
            u /= 10
        return u * 10


App().mainloop()

注释中的
mike-smt
解释了原因,这是因为有了括号,Python在读取代码时执行函数,但没有括号(括号),Python将其视为以后可以调用的函数的引用

我发现避免这种情况的最好方法是使用
lambda
函数

这是最好的解释,但我会尝试总结在这里

正如我所说的,当一个按钮被创建时,它将运行您希望在单击它时运行的命令

要创建使用参数调用button函数的lambda函数,请执行以下操作:

lambda: button('ping pong')
最终得到的函数在功能上等同于:

def function():
    button('ping pong')
lambda
返回对该无名函数的引用。由于引用是命令选项所期望的,因此可以在创建按钮时直接使用lambda

所以不是

btn=按钮(窗口,text=“Function1”,命令=单击(标签1))
使用
lambda
函数如下调用自定义函数

btn=按钮(窗口,text=“Function1”,command=lambda:clicked('label1'))

command参数应该是一个函数,而不是对函数的调用。您在创建按钮时调用函数,而不是在他们单击按钮时调用函数。
command=lambda:clicked(label1)
@Barmar a lambda是一个滥杀。只需单击
command=clicked
即可。op只需要将主GUI代码移到全局名称空间。@Mike SMT我假设他需要
标签
参数。Tkinter在创建按钮函数时运行按钮函数。。。不完全是。Tkinter与这种行为无关。这就是Python的工作方式。原因是,有了括号,python在读取代码时执行函数,但没有括号,python将其视为对稍后调用的函数的引用。@Mike SMT谢谢,我将编辑答案并修复它