Как получить атрибут из экземпляра другого класса? - PullRequest
0 голосов
/ 27 декабря 2018

В течение недели я боролся с упом в Python, когда писал приложение для tkinter.Я упростил приложение, чтобы показать только проблему.У меня есть два кадра, и у каждого из них есть две кнопки - кнопка в первом ряду увеличивает номер кадра (self.top_frame_number или self.bottom_frame_number, а кнопка во втором ряду должна получить мне номер из другого кадра (поэтомукнопка в верхнем фрейме должна получить номер из нижнего фрейма).

Я не могу понять, как это сделать, это означает, что я не знаю, как получить доступ к атрибуту экземпляра класса из другогоэкземпляр класса, хотя оба они являются атрибутами основного класса Application.

Я искал вопросы, но не нашел аналогичного примера, и ответы на другие вопросы не помогли мне в моей борьбеВот весь код:

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()

Я пытался узнать ооп из различных материалов через Интернет, но безуспешно. Поэтому я попытался:

  1. наследование -это как-то сработало, но я не хочу использовать наследование, так как классы TopFrame и BottomFrame равны, а не состав "родитель-ребенок"
  2. - я не смогo исправить это с помощью композиции (= инициализировать другой класс в __init__, так как это приведет к бесконечной ошибке рекурсии.

Как правильно получить доступ к номеру в экземпляре другого класса?

1 Ответ

0 голосов
/ 28 декабря 2018

Джейсонхарпер указал мне правильное направление.Я добавил ссылку на мастер-класс Application, и он работает.Таким образом, весь код выглядит так:

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()

Если есть лучший способ, как ссылаться на класс Application из классов TopFrame или BottomFrame без указания self в Application´s __init__ (это означает без self.top_frame = TopFrame(self.master, self) и self.bottom_frame = BottomFrame(self.master, self)) и соответствующие ссылки в классах TopFrame и BottomFrame (self.master = master), я открытый ...

...