Как получить доступ к атрибутам в другом подклассе фреймов tkinter?

#tkinter #python-3.8

Вопрос:

Я пытаюсь войти self.var_1 frame_2 и self.var_2 войти frame_1 ?

Вот мой код.

 import tkinter as tk


class Root(tk.Tk):
    def __init__(self):
        super().__init__()
        self.frame_1 = Frame1(self)
        self.frame_1.pack()
        self.frame_2 = Frame2(self)
        self.frame_2.pack()


class Frame1(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master)
        self.var_1 = 'Variable_1'


class Frame2(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master)
        self.var_2 = 'Variable_2'


if __name__ == '__main__':
    root = Root()
    root.mainloop()
 

Я попробовал это.

 class Frame2(tk.Frame):
    
        def __init__(self, master=None):
            super().__init__(master)
            self.var_2 = 'Variable_2'
            self.var_1 = self.master.frame_1.var_1
 

Но это не сработает Frame1 , потому self.master.frame_2.var_2 что не определено.

 class Frame1(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master)
        self.var_1 = 'Variable_1'
        self.var_2 = self.master.frame_2.var_2
 

Комментарии:

1. создайте метод, который установит эти значения, а затем вызовет его в основном классе после инициализации обоих этих классов

2. Я не понимал этого, пока не понял сам! В любом случае, спасибо за помощь.

Ответ №1:

Поскольку вы передаете экземпляр Root as master при создании экземпляров Frame1 and Frame2 , и поскольку экземпляр Root имеет ссылки на фреймы, один из способов-сохранить ссылку на master :

 class Frame1(tk.Frame):   
    def __init__(self, master):
        super().__init__(master)
        self.root = master
        self.var_1 = 'Variable_1'
 

При этом вы можете использовать self.root.frame_1.var_1 и self.root.frame_2.var_2 в обоих Frame1 и Frame2 .

Другим решением может быть добавление метода Root , который возвращает один или оба кадра. Например, вы могли бы определить get_frames так:

 class Root:
    ...
    def get_frames(self):
        return self.frame_1, self.frame_2
 

Затем вы можете вызвать этот метод для получения кадров, а затем использовать кадр для получения переменной:

 frame1, frame2 = self.root.get_frames()
print(frame1.var_1)
 

Трудно сказать, какое решение лучше всего использовать на этом простом примере. Независимо от этого, это не проблема tkinter, это просто фундаментальный аспект объектно-ориентированного программирования: для доступа к атрибуту объекта вам нужна ссылка на объект. Вы можете либо попросить абонента передать его, либо вы можете забрать его, когда он вам понадобится.

Комментарии:

1. Я думаю, что это происходит self.master = master автоматически, хотя я сделал это в обоих направлениях, но это все равно выдает ошибку 😥. И просто Frame1(self) повторив это, он будет работать, но когда-нибудь он дублируется в tkinter, что и ожидается..

2. @Рожьяргайлан: вы правы. Я сам не использую «мастер» и забываю, что это делает tkinter. Я изменил имя этой переменной в своем ответе.

3. @RozhyarGaylan: вы, конечно, не можете ссылаться на переменную в другом классе до создания экземпляра другого класса.

4. Можно ли это сделать с помощью потоковой или многопроцессорной обработки?

5. @RozhyarGaylan: нет, это не поможет вам получить доступ к тому, чего не существует. Чего вы ожидаете добиться, пытаясь ссылаться на то, что еще не создано?