如何从另一个继承的tkinter类访问一个继承tkinter类中的方法



我以前使用tkinter进行过编程,但通常会创建一个长过程GUI类来实现我创建的其他非GUI类。这一次,我想使用更多的OOP,使其更加模块化。

我遇到了一个问题,我一直在寻找答案,但没有找到任何答案,这通常意味着要么很容易,要么我真的错了。我从tk.LabelFrame创建了一个继承的类,并在其中创建了GUI小部件。我也有方法来操作类中的小部件,但我不知道如何在另一个继承类中执行函数,部分原因是我不知道怎样正确地实例化另一个类中的对象(这些类将tkinter('parent')对象作为参数)。

我会通过重载构造函数来实现这一点吗?我看到了一些关于@classmethods和*args、**kwargs的内容,但还没有对它们采取行动,因为我也不确定这是否是正确的方法。关于在python中实现重载构造函数的最佳/正确方法,存在一些争论。我很困惑,对于我正在努力实现的目标,什么是最合适的。。。

感谢

#python 2.7 on win7
import Tkinter as tk
class Testing(tk.LabelFrame):
    buttonwidth = 10
    def __init__(self, parent):
        self.parent=parent
        #results = Results(???) #<-- Don't know how to instantiate Results object
        tk.LabelFrame.__init__(self, self.parent, 
            text="Test Operations",
            padx=10,
            pady=10,
        )
        self.taskButton = tk.Button(
            self, 
            text="Do A Task", 
            width=self.buttonWidth,
            command=self.doATask,
        )
        self.taskButton.pack()
    def doATask(self):
        #want to execute function in Results.getResult() but don't know how
        #results.getResults()  #<--what I want to do
        print("place holder")
class Results(tk.LabelFrame):
    def __init__(self, parent):
        self.parent = parent
        tk.LabelFrame.__init__(self, self.parent, text="Visual Results")
        self.resultLbl = tk.Label(self, text="Result")
        self.resultLbl.pack()
    def getResult(self):
        self.resultLbl.configure(bg='yellow')

class Application(tk.Frame):
    def __init__(self, parent):
        self.parent = parent
        tk.Frame.__init__(self, self.parent)
        self.Testing = Testing(self.parent)
        self.Results = Results(self.parent)
        self.Testing.pack(fill=tk.X)
        self.Results.pack(fill=tk.X)
if __name__ == "__main__":
    root = tk.Tk()
    root.title("Modular GUI App")
    Application(root).pack()
    root.mainloop()

我建议坚持使用为每个单独对象创建的实例变量,而不是在类的所有实例化之间共享的类变量-只需在这些变量名前面加上self.(例如self.results)。此外,要坚持命名约定,这样就不会有Testing类和该类的Testing对象。

您可以根据对象的__init__实例化对象。Results类有一个定义为def __init__(self, parent):__init__,因此它需要一个父级。如果希望它与创建它的Testing对象具有相同的父对象,只需执行results = Results(parent)即可。但是,您不希望这样做(请参见下文)。

在进行上述更改后,我遇到的一个问题是Application类实例化了它自己的Results对象,而这正是实际显示的内容,而不是Testing对象创建的内容。请重新引用该对象,而不是创建一个新对象。将Application对象传递给这些类中的每一个,以便它们可以相互引用。话虽如此,通常最好让每个类尽可能少地了解其他类,这样在一个类中进行更改就不需要在其他类中进行任何更改。

当您单击按钮时,以下代码将使标签变为黄色。

import Tkinter as tk
class Testing(tk.LabelFrame):
    def __init__(self, parent, main):
        self.buttonWidth = 10
        self.parent=parent
        self.main = main # save the instantiating class
        tk.LabelFrame.__init__(self, self.parent, 
            text="Test Operations",
            padx=10,
            pady=10
        )
        self.taskButton = tk.Button(
            self, 
            text="Do A Task", 
            width=self.buttonWidth,
            command=self.doATask,
        )
        self.taskButton.pack()
    def doATask(self):
        #want to execute function in Results.getResult() but don't know how
        self.main.results.getResult()  #<--what you can do
class Results(tk.LabelFrame):
    def __init__(self, parent, main):
        self.parent = parent
        self.main = main # save the instantiating class
        tk.LabelFrame.__init__(self, self.parent, text="Visual Results")
        self.resultLbl = tk.Label(self, text="Result")
        self.resultLbl.pack()
    def getResult(self):
        self.resultLbl.config(bg='yellow')
class Application(tk.Frame):
    def __init__(self, parent):
        self.parent = parent
        tk.Frame.__init__(self, self.parent)
        self.testing = Testing(self.parent, self)
        self.results = Results(self.parent, self)
        self.testing.pack(fill=tk.X)
        self.results.pack(fill=tk.X)
if __name__ == "__main__":
    root = tk.Tk()
    root.title("Modular GUI App")
    Application(root).pack()
    root.mainloop()

这对我有效

Results(None,None).getResult()

祝你好运!

最新更新