繁体   English   中英

为什么 Label 在此代码中没有随 StringVar 改变? (tkinter)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM