Вызов функции из другого класса

ЗИЛ

Новичок
Пользователь
Янв 3, 2022
43
1
8
Как правильно вызвать функцию из другого класса Tkinter
Пример кода:
Python:
from tkinter import *
from PIL import Image, ImageTk

class ToolBar(Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
       
        self.configure(height = 100)
       
        self.image1 = Image.open( "./path/to/image")
        self.resize_image1 = self.image1.resize((32, 32))
        self.img1 = ImageTk.PhotoImage(self.resize_image1)
       
        btn = Button(self, image = self.img1, command = self.f_click)
        btn.pack()
       
    def f_click(self):
       
        example = Example()
        example.click()

class Example(Tk):
    def __init__(self, parent=None, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
       
        self.minsize(width = 500, height = 500)
        menubar = Menu(self, background='#FFD39B', foreground='black', activebackground='#F0FFFF', activeforeground='black')
        push_menu = Menu(menubar, tearoff = 0)
        menubar.add_cascade(label = 'Текст', menu = push_menu)
        push_menu.add_command(label = 'Применить', command = self.click)
        self.config(menu=menubar)
       
        self.text = Text(self)
       
        tlbr = ToolBar(self)
        tlbr.pack(side = 'top', fill = 'x')
        self.text.pack(fill = 'both', expand = True)
       
    def click(self):
        self.text.configure(font = "Helvetica 16 bold")

if __name__ == '__main__':
   
    example = Example()
    example.mainloop()

Ошибка: при запуске появляется ещё одно окно (TopLevel?) и текст ошибки:
_tkinter.TclError: image "pyimage2" doesn't exist

Подскажите что я сделал не так.
 

Vershitel_sudeb

Vershitel sudeb
Команда форума
Модератор
Мар 17, 2021
971
219
43
20
Москва
Python:
from tkinter import *
from PIL import Image, ImageTk

path2image = r"D:\Images\Images\logo\manim_dark_logo.png"


class ToolBar(Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        self.configure(height=100)
        self.buttons = []

    def add_batton(self, command, image):
        """
        Добавление кнопки в тулбар

        Args:
            command (func): функция вызываемая при нажатии кнопки
            image (str): Путь к изображению
        """
        # Открываем изображение
        image = Image.open(image).resize((32, 32))
        # Преобразуем и сохраняем изображение
        self.buttons.append([ImageTk.PhotoImage(image)])
        # Создаем кнопку
        self.buttons[-1].append(
            Button(self, image=self.buttons[-1][0], command=command)
        )
        # Добавляем кнопку
        self.buttons[-1][1].pack(side="left")


class Example(Tk):
    def __init__(self, parent=None, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        self.minsize(width=500, height=500)
        menubar = Menu(
            self,
            background="#FFD39B",
            foreground="black",
            activebackground="#F0FFFF",
            activeforeground="black",
        )
        push_menu = Menu(menubar, tearoff=0)
        menubar.add_cascade(label="Текст", menu=push_menu)
        push_menu.add_command(label="Применить", command=self.click)
        self.config(menu=menubar)

        self.text = Text(self)

        # ! Добавляем тулбар
        tlbr = ToolBar(self)
        tlbr.pack(side="top", fill="x")

        # Добавляем кнопки
        tlbr.add_batton(self.click, path2image)
        tlbr.add_batton(lambda: print("btn_2 click"), path2image)
        tlbr.add_batton(lambda: print("btn_3 click"), path2image)

        self.text.pack(fill="both", expand=True)

    def click(self):
        self.text.configure(font="Helvetica 16 bold")


if __name__ == "__main__":
    example = Example()
    example.mainloop()
 

ЗИЛ

Новичок
Пользователь
Янв 3, 2022
43
1
8
Насколько я понимаю -- добавлять кнопки нужно в классе где мы создаём меню?
Это хорошо, но тогда теряется смысл в классе ToolBar.
Я его сделал только чтобы уменьшить кол-во кода в основном классе(который от Tk).
Тут вопрос только в том что мне нужно привязать и меню и кнопку тулбара к одному обработчику.
Нельзя ли назначить обработчик для кнопок тулбара в классе Example?
Что то вроде
Python:
self.btn(command = self.click)
?
 
Последнее редактирование:

ЗИЛ

Новичок
Пользователь
Янв 3, 2022
43
1
8
Решено.
Убрал картинки чтобы не заморачиваться.
Код:
Python:
from tkinter import *
from PIL import Image, ImageTk
class ToolBar(Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.configure(height=100)
    
        self.btn = Button(self)
        self.btn.pack()
        
class Example(Tk):
    def __init__(self, parent=None, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.minsize(width=500, height=500)
        menubar = Menu(self, background='#FFD39B', foreground='black', activebackground='#F0FFFF',
                       activeforeground='black')
        push_menu = Menu(menubar, tearoff=0)
        menubar.add_cascade(label='Текст', menu=push_menu)
        push_menu.add_command(label='Применить', command=self.click)
        self.config(menu=menubar)
        self.text = Text(self)
        tlbr = ToolBar(self)
        tlbr.btn.configure(command=self.click)#вот здесь задаём обработчик
        tlbr.pack(side='top', fill='x')
        self.text.pack(fill='both', expand=True)
    def click(self):
        self.text.configure(font="Helvetica 16 bold")
if __name__ == '__main__':
    example = Example()
    example.mainloop()
 

Форум IT Специалистов