Не получается передать значения из одного класса в другой, хотя внутри класса всё работает

Имеются 3 класса:

  1. BasicMode — левый фрейм,
  2. AdvancedMode — правый фрейм,
  3. Calculator — объединяющий оба фрейма в один.

При нажатии на клавиши из правого фрейма, передаётся информация в левый фрейм в метод working_adv_mode_btn. Несмотря на то, что в терминале значение выдаётся, но на экран не выводится, хотя при нажатии клавиш левого фрейма, вся информация на экране отображается. В чем причина? Также при закрытии программы всё виснет!

from tkinter import *
from tkinter.ttk import Frame, Button, Style


class BasicMode(Frame):
    def __init__(self, master):
        super().__init__()
        self.master = master
        self.my_window()

    def make_digit_button(self, digit):  # rr создание цифровых кнопок
        return Button(self, text=digit, command=lambda: self.working_adv_mode_btn(digit))

    def my_window(self):
        Style().configure('one.TButton', background='red')
        # yy показываем основной дисплей
        self.text_field = Text(self, foreground='black', padx=10, pady=5, relief='sunken', bd=5,
                               font=('serif', 14, 'bold'), height=1, width=20)
        self.text_field.grid(row=0, columnspan=4, sticky='we', padx=5, pady=(5, 10))
        self.clb = Button(self, text='?', style='one.TButton', command=lambda: self.master.mode_switch())
        self.clb.grid(row=1, column=0)
        # yy Оформление кнопок

        for num, val in enumerate(['6', '7', '8', '9']):
            self.make_digit_button(val).grid(row=3, column=num)
        for num, val in enumerate(['2', '3', '4', '5']):
            self.make_digit_button(val).grid(row=4, column=num)
        for num, val in enumerate(['0', '1', '.', '']):
            self.make_digit_button(val).grid(row=5, column=num)

    def working_adv_mode_btn(self, action):
        self.text_field.insert(END, action)
        print(action)


class AdvancedMode(Frame):
    def __init__(self, master):
        super().__init__()
        self.master = master
        self.additional_buttons()

    def creating_adv_mode_btn(self, sym):  # rr создание дополнительных кнопок
        return Button(self.frame_btn, text=sym, style='add_btn_color.TButton',
                      command=lambda: BasicMode(None).working_adv_mode_btn(sym))

    def additional_buttons(self):
        self.frame_btn = Frame(self)  # создаём новый фрейм
        self.frame_btn.pack()
        opts = {'padx': (2, 2), 'pady': (2, 2)}
        for num, val in enumerate(['mod', 'tanh', 'ln', 'x³']):  # выводим на экран новые кнопки
            self.creating_adv_mode_btn(val).grid(row=0, column=num, **opts)
        for num, val in enumerate(['exp', 'asin', 'acos', '']):
            self.creating_adv_mode_btn(val).grid(row=1, column=num, **opts)


class Calculator(Tk):
    def __init__(self):
        super().__init__()
        self.title("Калькулятор - базовый режим")
        self.trigger = True
        self.frame_a = BasicMode(self)
        self.frame_a.pack(side=LEFT, padx=10, pady=10)
        self.frame_b = AdvancedMode(self)
        self.frame_b.pack(side=RIGHT, padx=10, pady=10)
        self.frame_b.pack_forget()

    def mode_switch(self):  # переключатель режимов
        if self.trigger:
            self.title("Калькулятор - расширенный режим")
            self.frame_b.pack()
            # yy изменение размера многострочного текстового поля
            self.frame_a.text_field['height'] = 8
            self.trigger = False
        else:
            self.title("Калькулятор - базовый режим")
            self.frame_a.text_field['height'] = 1
            self.frame_b.pack_forget()
            self.trigger = True


if __name__ == '__main__':
    app = Calculator()
    app.mainloop()

Ответы (1 шт):

Автор решения: MarianD

Вместо такого определения метода creating_adv_mode_btn() в классе AdvancedMode:

def creating_adv_mode_btn(self, sym):  # rr создание дополнительных кнопок
    return Button(self.frame_btn, text=sym, style='add_btn_color.TButton',
                  command=lambda: BasicMode(None).working_adv_mode_btn(sym))
                  

когда вы (в последней строке этого кода) создаете в lambda-функции новый экземпляр класса BasicMode, примените

def creating_adv_mode_btn(self, sym):  # rr создание дополнительных кнопок
    return Button(self.frame_btn, text=sym, style='add_btn_color.TButton',
                  command=lambda: app.frame_a.working_adv_mode_btn(sym))

в котором вы используете существующий экземпляр app.frame_a - ваш левый фрейм.

→ Ссылка