【问题标题】:How to access a method in one inherited tkinter class from another inherited tkinter class如何从另一个继承的 tkinter 类访问一个继承的 tkinter 类中的方法
【发布时间】:2015-09-19 03:49:09
【问题描述】:

我以前使用 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()

【问题讨论】:

    标签: python user-interface inheritance tkinter


    【解决方案1】:

    这对我有用

    Results(None,None).getResult()
    

    祝你好运!

    【讨论】:

      【解决方案2】:

      我建议坚持使用为每个单独的对象创建的实例变量,这与在所有类的实例之间共享的类变量不同——只需在这些变量名称前加上self.(例如self.results)。此外,请遵守命名约定,这样您就没有 Testing 类和该类的 Testing 对象。

      您根据对象的__init__ 实例化对象。 Results 类有一个 __init__ 定义为 def __init__(self, parent):,所以它需要一个父类。如果您希望它与创建它的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()
      

      【讨论】:

      • 优秀...我一直在想我需要找到一种方法来重载构造函数,但对我来说似乎不太合适。这就是我需要的。我会记住你所说的让班级互相忘记的说法。
      猜你喜欢
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-22
      • 1970-01-01
      相关资源
      最近更新 更多