如何通过使用tkinter来修改一个班级中另一个班级中正在使用的变量?

我要完成的是一种在另一个类实例中更改变量的方法。我一直在摸索,试图了解这是怎么可能的。

  

如何更新类中的self.lblvar的值   来自MainWindow类的SecondWindow

这就是我用来检验我的理论的东西:

from tkinter import *

class MainWindow:
    def __init__(self,rootWin):
        self.rootWin = rootWin
        self.rootWin.geometry('400x200')

        self.mainmenu = Menu(self.rootWin)
        self.mainmenu.add_command(label = 'Open Second Window',command = self.openSecondWindow)

        self.lblvar = StringVar()
        self.lblvar.set('Change Me!')
        self.lbl = Label(rootWin,textvariable = self.lblvar)
        self.lbl.pack()

        self.rootWin.config(menu = self.mainmenu)

    def openSecondWindow(self):
        self.secondWin = Tk()
        self.secWin = SecondWindow(self)
        self.secondWin.mainloop()

class SecondWindow:
    def __init__(self,parent):
        self.parent = parent

        self.btn = Button(self,label = 'Change Label?',command = self.changeOther)
        self.btn.pack()

    def changeOther(self):
        self.parent.lblvar.set('Changed it!')

def main():
    root = Tk()
    mainWin = MainWindow(root)
    root.mainloop()

if __name__ == "__main__":
    main()

关于Python类,我还是个新手,因此对此有任何指导和/或解释将不胜感激!

编辑:将原始问题更改为更清楚的问题,以帮助对该主题进行进一步的搜索

wxt112 回答:如何通过使用tkinter来修改一个班级中另一个班级中正在使用的变量?

是的。完全有可能从另一个类中修改类或类实例的状态。与传统的OOP语言(例如C ++)不同,Python不执行任何访问规则-一切都是公共的。

class ClassA:
    def __init__(self,var_a):
        self.var_a = var_a

    def change_var_c(self,instance_b,new_value):
        instance_b.var_c = new_value

    def change_var_b(self,new_value):
        ClassB.VAR_B = new_value

class ClassB:
    VAR_B = 2
    def __init__(self,var_c):
        self.var_c = var_c


instance_a = ClassA(1)
instance_b = ClassB(3)

instance_a.change_var_c(instance_b,4)
print(instance_b.var_c) # prints 4

instance_a.change_var_b(5)
print(ClassB.VAR_B) # prints 5

尽管如此,这可能不是您应该执行的操作。修改对象的内部违反了封装原理。类应该改为公开公共接口来修改其“私有”成员。

,

因此,使代码按预期工作需要进行的最小更改将是更改您的类SecondWindow来接受2个争论,一个争论是针对顶级窗口,一个争论针对主窗口类,以及更改方法openSecondWindow以使用Toplevel窗口而不是Tk的第二实例,因为您在tkinter GUI中绝对不能使用多个Tk()实例。一个小问题是您在按钮内使用了label =,而实际上应该是text=。所有这些使我们可以使用class属性。

类似这样的东西:

def openSecondWindow(self):
    self.secondWin = Toplevel(self.rootWin)
    self.secWin = SecondWindow(self.secondWin,self)

class SecondWindow:
    def __init__(self,top,master):
        self.master = master

        self.btn = Button(top,text='Change Label?',command=self.changeOther)
        self.btn.pack()

    def changeOther(self):
        self.master.lblvar.set('Changed it!')

那就是说,我将整体上进行一些更改以提高可读性并减少代码行。

  1. import tkinter as tk而不是使用*。这将有助于防止覆盖内置方法/其他导入,并明确您在代码中使用的库。

  2. 从类中的Tk()Toplevel()继承,使事情更容易处理。

  3. 仅在需要的地方使用self.。在代码中的某些位置是不需要的。

请参见下面的重做示例,如果您有任何疑问,请告诉我:

import tkinter as tk


class MainWindow(tk.Tk):
    def __init__(self):
        # super is used to avoid referring to the base class explicitly.
        # to read more on this check out the link below.
        super().__init__()
        self.geometry('400x200')
        main_menu = tk.Menu(self)
        self.config(menu=main_menu)
        main_menu.add_command(label='Open Second Window',command=SecondWindow)
        self.lblvar = tk.StringVar(value='Change Me!')
        # No need to use `self.` on this label as we are working with the lblvar in the 2nd window and not the label.
        tk.Label(self,textvariable=self.lblvar).pack()


class SecondWindow(tk.Toplevel):
    def __init__(self):
        super().__init__()
        # No need to use `self.` on this button unless down the road you want to change this button in some way.
        tk.Button(self,command=self.change_other).pack()

    def change_other(self):
        # with inheriting like this in tkinter you do not need to define self.master as it is automatic here.
        # Other classes or methods may need it defined however. Just wanted to make sure you are aware of this.
        self.master.lblvar.set('Changed it!')


if __name__ == "__main__":
    MainWindow().mainloop()

结果:

enter image description here

有关super()的更多详细信息。

本文链接:https://www.f2er.com/3122595.html

大家都在问