【问题标题】:How to get an attribute from another class´ instance?如何从另一个类的实例中获取属性?
【发布时间】:2019-05-25 12:49:29
【问题描述】:

在编写 tkinter 应用程序时,我在 Python 中的 oop 苦苦挣扎了一周。我已经简化了应用程序以仅显示问题。我有两个框架,每个框架都有两个按钮 - 第一行中的按钮增加了框架的数量(self.top_frame_numberself.bottom_frame_number,第二行中的按钮应该让我从另一个框架中获得一个数字(所以顶部框架中的按钮应该让我得到底部框架中的数字)。

我不知道如何做到这一点,这意味着我不知道如何从另一个类的实例访问一个类的实例属性,而它们都是主应用程序类的属性。

我一直在搜索问题,但没有找到类似的例子,其他问题的答案对我的斗争没有帮助。这是整个代码:

import tkinter as tk

class TopFrame:
    def __init__(self, parent):
        self.parent = parent
        self.topframe = tk.LabelFrame(self.parent, text="Top frame", width=300, height=100, bd=2)
        self.topframe.pack(side="top", fill="both")

        self.top_frame_number = 100

        # FIRST ROW WIDGETS
        self.topframe_tfn_label = tk.Label(self.topframe, text="number: ")
        self.topframe_tfn_label.grid(row=0, column=0, sticky="w")

        self.topframe_tfn = tk.Label(self.topframe)
        self.topframe_tfn.grid(row=0, column=1)
        self.topframe_tfn.configure(text=self.top_frame_number)

        self.topframe_tfn_button = tk.Button(self.topframe,
                                         text="increase",
                                         command=lambda: self.topframe_increase_top_frame_number())
        self.topframe_tfn_button.grid(row=0, column=2, pady=2, sticky="w")

        # SECOND ROW WIDGETS
        self.topframe_bfn_label = tk.Label(self.topframe, text="bottom frame number: ")
        self.topframe_bfn_label.grid(row=1, column=0, sticky="w")

        self.topframe_bfn = tk.Label(self.topframe)
        self.topframe_bfn.grid(row=1, column=1)
        self.topframe_bfn.configure(text="?")

        self.topframe_bfn_button = tk.Button(self.topframe,
                                         text="get bottom frame number",
                                         command=lambda: self.topframe_get_bottom_frame_number())
        self.topframe_bfn_button.grid(row=1, column=2, pady=2, sticky="e")

    def topframe_increase_top_frame_number(self):
        self.top_frame_number += 1
        self.topframe_tfn.configure(text=self.top_frame_number)

    def topframe_get_bottom_frame_number(self):
        pass
        # I AM STUCK HERE - How to get to the top frame number?

class BottomFrame:
    def __init__(self, parent):
        self.parent = parent
        self.bottomframe = tk.LabelFrame(self.parent, text="Bottom frame", width=300, height=100, bd=2)
        self.bottomframe.pack(side="top", fill="both")

        self.bottom_frame_number = 200

        # FIRST ROW
        self.bottomframe_tfn_label = tk.Label(self.bottomframe, text="number: ")
        self.bottomframe_tfn_label.grid(row=0, column=0, sticky="w")

        self.bottomframe_tfn = tk.Label(self.bottomframe)
        self.bottomframe_tfn.grid(row=0, column=1)
        self.bottomframe_tfn.configure(text=self.bottom_frame_number)

        self.bottomframe_tfn_button = tk.Button(self.bottomframe,
                                            text="increase",
                                            command=lambda: self.bottomframe_increase_bottom_frame_number())
        self.bottomframe_tfn_button.grid(row=0, column=2, pady=2, sticky="e")

        # SECOND ROW
        self.bottomframe_bfn_label = tk.Label(self.bottomframe, text="top frame number: ")
        self.bottomframe_bfn_label.grid(row=1, column=0, sticky="w")

        self.bottomframe_bfn = tk.Label(self.bottomframe)
        self.bottomframe_bfn.grid(row=1, column=1)
        self.bottomframe_bfn.configure(text="?")

        self.bottomframe_bfn_button = tk.Button(self.bottomframe,
                                            text="get top frame number",
                                            command=lambda: self.bottomframe_get_top_frame_number())
        self.bottomframe_bfn_button.grid(row=1, column=2, pady=2, sticky="e")

    def bottomframe_increase_bottom_frame_number(self):
        self.bottom_frame_number += 1
        self.bottomframe_tfn.configure(text=self.bottom_frame_number)

    def bottomframe_get_top_frame_number(self):
        pass
        # I AM STUCK HERE - How to get to the top frame number?

class Application:
    def __init__(self, master):
        self.master = master
        self.master.title("Show me numbers!")

        # -- FRAMES --
        self.top_frame = TopFrame(self.master)
        self.bottom_frame = BottomFrame(self.master)

if __name__ == "__main__":
    root = tk.Tk()

    Application(root)
    root.mainloop()

我一直在尝试从网络上的不同材料中学习 oop,但没有成功。所以我尝试了:

  1. 继承 - 它以某种方式工作,但我不想使用继承,因为 TopFrameBottomFrame 类是相等的,而不是父子类
  2. 组合 - 我无法使用组合修复它(=初始化 __init__ 中的另一个类,因为它会导致无限递归错误。

我应该如何正确访问其他类实例中的号码?

【问题讨论】:

  • 每个 Frame 都有对父级的引用。父级对两个框架都有引用。所以,self.master.bottom_frame.bottom_frame_number 应该从顶部框架开始工作。
  • 每个Frame都有对父级的引用,但是这里的父级指向的是root,而不是Application类。
  • 但是我手动添加了对 Application 类的引用,它可以工作。是否有另一种方法可以从 TopFrame 或 BottomFrame 中引用 Application 类?无论如何,感谢您为我指明正确的方向!

标签: python-3.x class tkinter instance-variables


【解决方案1】:

jasonharper 为我指明了正确的方向。我添加了对主应用程序类的引用,它可以工作。所以整个代码是:

import tkinter as tk

class TopFrame:
    def __init__(self, parent, master):
        self.parent = parent
        self.master = master
        self.topframe = tk.LabelFrame(self.parent, text="Top frame", width=300, height=100, bd=2)
        self.topframe.pack(side="top", fill="both")

        self.top_frame_number = 100

        # FIRST ROW
        self.topframe_tfn_label = tk.Label(self.topframe, text="number: ")
        self.topframe_tfn_label.grid(row=0, column=0, sticky="w")

        self.topframe_tfn = tk.Label(self.topframe)
        self.topframe_tfn.grid(row=0, column=1)
        self.topframe_tfn.configure(text=self.top_frame_number)

        self.topframe_tfn_button = tk.Button(self.topframe,
                                         text="increase",
                                         command=lambda: self.topframe_increase_top_frame_number())
        self.topframe_tfn_button.grid(row=0, column=2, pady=2, sticky="w")

        # SECOND ROW
        self.topframe_bfn_label = tk.Label(self.topframe, text="bottom frame number: ")
        self.topframe_bfn_label.grid(row=1, column=0, sticky="w")

        self.topframe_bfn = tk.Label(self.topframe)
        self.topframe_bfn.grid(row=1, column=1)
        self.topframe_bfn.configure(text="?")

        self.topframe_bfn_button = tk.Button(self.topframe,
                                         text="get bottom frame number",
                                         command=lambda: self.topframe_get_bottom_frame_number())
        self.topframe_bfn_button.grid(row=1, column=2, pady=2, sticky="e")

    def topframe_increase_top_frame_number(self):
        self.top_frame_number += 1
        self.topframe_tfn.configure(text=self.top_frame_number)

    def topframe_get_bottom_frame_number(self):
        self.topframe_bfn.configure(text=self.master.bottom_frame.bottom_frame_number)


class BottomFrame:
    def __init__(self, parent, master):
        self.parent = parent
        self.master = master
        self.bottomframe = tk.LabelFrame(self.parent, text="Bottom frame", width=300, height=100, bd=2)
        self.bottomframe.pack(side="top", fill="both")

        self.bottom_frame_number = 200

        # FIRST ROW
        self.bottomframe_bfn_label = tk.Label(self.bottomframe, text="number: ")
        self.bottomframe_bfn_label.grid(row=0, column=0, sticky="w")

        self.bottomframe_bfn = tk.Label(self.bottomframe)
        self.bottomframe_bfn.grid(row=0, column=1)
        self.bottomframe_bfn.configure(text=self.bottom_frame_number)

        self.bottomframe_bfn_button = tk.Button(self.bottomframe,
                                            text="increase",
                                            command=lambda: self.bottomframe_increase_bottom_frame_number())
        self.bottomframe_bfn_button.grid(row=0, column=2, pady=2, sticky="e")

        # SECOND ROW
        self.bottomframe_tfn_label = tk.Label(self.bottomframe, text="top frame number: ")
        self.bottomframe_tfn_label.grid(row=1, column=0, sticky="w")

        self.bottomframe_tfn = tk.Label(self.bottomframe)
        self.bottomframe_tfn.grid(row=1, column=1)
        self.bottomframe_tfn.configure(text="?")

        self.bottomframe_tfn_button = tk.Button(self.bottomframe,
                                            text="get top frame number",
                                            command=lambda: self.bottomframe_get_top_frame_number())
        self.bottomframe_tfn_button.grid(row=1, column=2, pady=2, sticky="e")

    def bottomframe_increase_bottom_frame_number(self):
        self.bottom_frame_number += 1
        self.bottomframe_bfn.configure(text=self.bottom_frame_number)

    def bottomframe_get_top_frame_number(self):
        self.bottomframe_tfn.configure(text=self.master.top_frame.top_frame_number)

class Application:
    def __init__(self, master):
        self.master = master
        self.master.title("Show me numbers!")

        # -- FRAMES --
        self.top_frame = TopFrame(self.master, self)
        self.bottom_frame = BottomFrame(self.master, self)

if __name__ == "__main__":
    root = tk.Tk()

    Application(root)
    root.mainloop()

如果有更好的方法如何从 TopFrame 或 BottomFrame 类中引用 Application 类,而无需在 Application 的 __init__ 中指定 self(这意味着没有 self.top_frame = TopFrame(self.master, self)self.bottom_frame = BottomFrame(self.master, self))以及在 TopFrame 和BottomFrame 类 (self.master = master),我思想开放...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多