[英]Why the Label is not changing with StringVar in this code? (tkinter)
代码环境:python 3.x
这是我的代码:
import tkinter as tk
def abc():
global Labelvar
Labelvar = tk.StringVar()
Labelvar.set('abc')
def xyz():
global Labelvar
Labelvar = tk.StringVar()
Labelvar.set('xyz')
class Application(tk.Tk):
def __init__(self):
super(self.__class__, self).__init__()
self.geometry('300x350')
self.show()
def show(self, labelvar=None):
bnt1 = tk.Button(self, text='a', command=abc)
bnt1.place(x=0, y=0)
bnt2 = tk.Button(self, text='b', command=xyz)
bnt2.place(x=0, y=50)
label1 = tk.Label(self, textvariable=labelvar)
label1.place(x=0, y=100)
if __name__ == '__main__':
app = Application()
app.mainloop()
当我按下按钮时,Label 没有响应,我该如何解决这个问题?
谢谢你。
因为您正在将 OO 编程与过程编程混合使用,并且使用您知道的全局变量就像魔鬼一样,除了将分配给 label 的变量命名为 Labelvar,另一个命名为 labelvar 之外,还有 class 之外的其他内容......但是我附上一个脚本 OO,部分是你的,向你展示如何继续,你必须在 class 的init中声明要分配给 textvariable 的变量,以使其对 class 的所有方法可见本身。 我提出了 palce() ,除非非常特殊的东西从未使用过。
#!/usr/bin/python3
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Simple App")
self.geometry('200x100')
self.protocol("WM_DELETE_WINDOW", self.on_close)
self.lablevar = tk.StringVar()
self.lablevar.set("Hello World!")
self.init_ui()
def init_ui(self):
f = ttk.Frame(self)
self.my_label = ttk.Label(f, textvariable=self.lablevar)
self.my_label.pack()
ttk.Button(f, text="A", command=self.set_label_value).pack()
ttk.Button(f, text="B", command=self.set_another_label_value).pack()
ttk.Button(f, text="Close", command=self.on_close).pack()
f.pack(fill=tk.BOTH, expand=0)
def set_label_value(self,):
self.lablevar.set("Ciao Mondo!")
def set_another_label_value(self,):
self.lablevar.set("Hola Mundo!")
def on_close(self, evt=None):
msg = "Do you want to quit?"
if messagebox.askokcancel(self.title(), msg, parent=self):
self.destroy()
def main():
app = App()
app.mainloop()
if __name__ == '__main__':
main()
这是您通过运行脚本立即执行的代码。
class Application(tk.Tk):
def __init__(self):
super(self.__class__, self).__init__()
self.geometry('300x350')
self.show()
def show(self, labelvar=None):
bnt1 = tk.Button(self, text='a', command=abc)
bnt1.place(x=0, y=0)
bnt2 = tk.Button(self, text='b', command=xyz)
bnt2.place(x=0, y=50)
label1 = tk.Label(self, textvariable=labelvar)
label1.place(x=0, y=100)
if __name__ == '__main__':
app = Application()
app.mainloop()
如果您逐行阅读该代码,从上到下,从左到右。 您将找到 class 的定义,当您作为 main 运行此脚本时,您将启动 class,因此__init__
方法运行。
然后,您可以调用 super ,其中包含 python 3.x 的不必要的 arguments ,并且可以缩短为super().__init__()
。 定位 window 后,您调用 class 的方法show
而不使用 arguments。 通过调用没有 arguments 的方法,使用默认参数,即None
。因此您对label1
的定义变为有效tk.Label(self, textvariable=None)
这个问题的解决方案有点武断,应该取决于你将来做什么。 如果您只想在 class 中访问此变量,这就是self
参数的用途,它为您提供了对实例的引用。 如果你想让它全局可用,你可以使用表达式global
或者在全局命名空间中定义一个变量。
因此,您想在实例之间共享所有内容,或者只是在其中保留引用。 您可以绑定/设置这些属性,例如self.labelvar = xy
。
我解决您的问题的建议是:
class Application(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('300x350')
self.labelvar = tk.StringVar()
self.show()
def show(self):
bnt1 = tk.Button(self, text='a', command=abc)
bnt1.place(x=0, y=0)
bnt2 = tk.Button(self, text='b', command=xyz)
bnt2.place(x=0, y=50)
label1 = tk.Label(self, textvariable=self.labelvar)
label1.place(x=0, y=100)
if __name__ == '__main__':
app = Application()
app.mainloop()
对于您在全局命名空间中定义的那些免费 function。 您可以决定将它们绑定到您的实例,方法是将它们放在 class 的命名空间中,并将参数 self 添加到它们,如下所示:
def abc(self):
self.labelvar.set('abc')
def xyz(self):
self.labelvar.set('xyz')
或者您决定将它们留在全局命名空间中并在 labelvar 上使用表达式 global 或在全局命名空间中定义 labelvar。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.