Python 3.x Tkinter-通过另一个函数更改标签文本
我知道经常使用面向对象编程(OOP)编写Tkinter GUI代码,但我尝试保持简单,因为我对Python不熟悉 我编写了以下代码来创建一个简单的GUI:Python 3.x Tkinter-通过另一个函数更改标签文本,python-3.x,tkinter,Python 3.x,Tkinter,我知道经常使用面向对象编程(OOP)编写Tkinter GUI代码,但我尝试保持简单,因为我对Python不熟悉 我编写了以下代码来创建一个简单的GUI: #!/usr/bin/python3 from tkinter import * from tkinter import ttk def ChangeLabelText(): MyLabel.config(text = 'You pressed the button!') def main(): Root = Tk()
#!/usr/bin/python3
from tkinter import *
from tkinter import ttk
def ChangeLabelText():
MyLabel.config(text = 'You pressed the button!')
def main():
Root = Tk()
MyLabel = ttk.Label(Root, text = 'The button has not been pressed.')
MyLabel.pack()
MyButton = ttk.Button(Root, text = 'Press Me', command = ChangeLabelText)
MyButton.pack()
Root.mainloop()
if __name__ == "__main__": main()
我原以为单击按钮时GUI(MyLabel)中的文本会变为“You pressed the button!”,但单击按钮时出现以下错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\elsey\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/Users/elsey/Documents/question code.py", line 6, in ChangeLabelText
MyLabel.config(text = 'You pressed the button!')
NameError: name 'MyLabel' is not defined
我做错了什么?任何指导都将不胜感激。
MyLabel
是main()
的本地版本,因此您无法通过ChangeLabelText()
以这种方式访问它
如果不想更改程序的设计,则需要更改ChangeLabelText()
的定义,如下所示:
def ChangeLabelText(m):
m.config(text = 'You pressed the button!')
使用main()时,需要将MyLabel
作为参数传递给ChangeLabelText()
但是,如果在声明和定义MyButton
时编写此command=ChangeLabelText(MyLabel)
代码,您将再次遇到问题,因为程序将在开始时直接执行ChangeLabelText()
的主体,并且不会得到所需的结果
要解决后面的问题,您必须使用(并且可能会阅读到)
完整程序
因此,您的程序变成:
#!/usr/bin/python3
from tkinter import *
from tkinter import ttk
def ChangeLabelText(m):
m.config(text = 'You pressed the button!')
def main():
Root = Tk()
MyLabel = ttk.Label(Root, text = 'The button has not been pressed.')
MyLabel.pack()
MyButton = ttk.Button(Root, text = 'Press Me', command = lambda: ChangeLabelText(MyLabel))
MyButton.pack()
Root.mainloop()
if __name__ == "__main__":
main()
演示
单击之前:
点击后:
但是我尽量保持简单,因为我是Python新手,希望这有助于理解类是最简单的方法,否则您必须跳转并手动跟踪许多变量。此外,《Python风格指南》还建议将CamelCase用于类名,并将小写的_加下划线用于变量和函数
您确定不想将其作为一个类来执行吗(我认为随着项目的发展,代码会变得更干净一些)?以下是一种实现您所寻找目标的方法:
#!/usr/bin/python3
from tkinter import *
from tkinter import ttk
class myWindow:
def __init__(self, master):
self.MyLabel = ttk.Label(root, text = 'The button has not been pressed.')
self.MyLabel.pack()
self.MyButton = ttk.Button(root, text = 'Press Me', command = self.ChangeLabelText)
self.MyButton.pack()
def ChangeLabelText(self, event=None):
self.MyLabel.config(text = 'You pressed the button!')
if __name__ == "__main__":
root = Tk()
mainWindow = myWindow(root)
root.mainloop()
在Mac电脑中,在按下按钮之前是这样的:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\elsey\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/Users/elsey/Documents/question code.py", line 6, in ChangeLabelText
MyLabel.config(text = 'You pressed the button!')
NameError: name 'MyLabel' is not defined
当你按下它时:
但基本上,为了能够更改标签或按钮中的文本,您需要确保它具有活动引用。在本例中,我们通过将窗口创建为一个类并引用表单
self中的小部件来实现。widget_name=widget()
您需要一个对象引用才能访问MyLabel最简单的解决方案是将全局MyLabel
添加到这两个函数中。但对于多个小部件来说,这很快就会变得一团糟。在某种程度上,一个或多个以小部件作为属性、以命令作为方法的类将获胜。感谢您的解决方案。我会将此标记为最佳答案,但我想我会尝试在代码中使用类。我认为如果不使用通配符导入,此答案会稍微好一点。是的,你说得很对。你最近也通过你对另一位成员的评论提到了这一点。我也会使用类,但OP说他是一个初学者,所以介绍他lambda和如何使用带参数的回调方法,我认为,对于初学者来说已经太多了,现在提到他PEPs可能还为时过早。正如人们常说的,大量的信息扼杀了信息。但是如果你阅读下面的内容,我对其中一个答案进行了评论,以鼓励OP使用OOP,我对下面的两个答案都投了赞成票。但是你还是对的@bryanoakley谢谢你的回答,谢谢你让我注意到你的风格指南。是的,开始学习这个好答案中所示的面向对象概念是很好的。谢谢你的回答。我感谢你的帮助。