繁体   English   中英

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

[英]How to access a method in one inherited tkinter class from another inherited tkinter class

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

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

我会通过重载构造函数来做到这一点吗? 我已经看过有关@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()

祝好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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