Как обновить изображение на кнопке в Tkinter?

#python #user-interface #tkinter

#python #пользовательский интерфейс #tkinter

Вопрос:

Когда я нажимаю на кнопку «apply_but», я хочу, чтобы изображение на этой кнопке было обновлено. Но это не работает. Другая проблема заключается в том, что когда я открываю это окно — «Вставка шума», также работает метод «кривые» и открывается другое окно с надписью «Что ты ищешь?». Но этот метод должен работать только после нажатия кнопки «img_but».

 class Noise(Toplevel):
    def __init__(self, pic):
        super().__init__()

        w = self.winfo_screenwidth() // 2 - 300  # ширина экрана
        h = self.winfo_screenheight() // 2 - 300  # высота экрана

        self.geometry('600x600 {} {}'.format(w, h))

        self.title('Noise insertion')
        self.resizable(width=False, height=False)
        self['bg'] = '#7be8cf'

        Label(self, text='Noise insertion', font=('Comic Sans MS', 20),
                       fg='#3d3d42', bg='#7be8cf').place(x=200, y=0)

        var = IntVar()
        var.set(0)
        var2 = IntVar()
        var2.set(0)

        self.yes_but = Radiobutton(self, text="Yes", variable=var, value=0,
                               font=('Comic Sans MS', 20),
                               width='10', height='1', activebackground='#e6f547',
                               bg='#7be8cf')
        self.no_but = Radiobutton(self, text="No", variable=var, value=1,
                              font=('Comic Sans MS', 20),
                              width='10', height='1', activebackground='#e6f547',
                              bg='#7be8cf')
        self.salt_but = Radiobutton(self, text="salt and peper", variable=var2, value=0,
                                font=('Comic Sans MS', 20),
                                width='10', height='1', activebackground='#e6f547',
                                bg='#7be8cf')
        self.gauss_but = Radiobutton(self, text="gauss noise", variable=var2, value=1,
                                 font=('Comic Sans MS', 20),
                                 width='10', height='1', activebackground='#e6f547',
                                 bg='#7be8cf')
        self.scale = Scale(self, orient=VERTICAL, from_=0, to=100, bg='#7be8cf',
                       activebackground='#e6f547', font='10',
                       highlightbackground='#7be8cf', label='%', fg='#f53be2')
        self.apply_but = Button(self, text='Apply', font=('Comic Sans MS', 10),
                            width='15', bg='grey', fg='white', bd=20, command=self.update_pic(pic))

        self.img_but = Button(self, image=pic, command = self.curves())

        # Pack()
        self.yes_but.place(x=0, y=100)
        self.no_but.place(x=0, y=50)
        self.salt_but.place(x=220, y=50)
        self.gauss_but.place(x=220, y=100)
        self.scale.place(x=500, y=50)
        self.apply_but.place(x=220, y=200)
        self.img_but.place(x=150, y=300)

    def update_pic(self, pic):
        var = self.scale.get()
        scale_res = self.scale.get()
        self.img = ImageTk.PhotoImage(get_pic('color_dragon.jpg', size= 
                              (300,200)).filter(ImageFilter.GaussianBlur))
        #self.img_but[image] = self.img ???

        pass

    def curves(self):
        Curves()
        pass

class Curves(Toplevel):
    def __init__(self):
        super().__init__()
        w = self.winfo_screenwidth() // 2 - 300  # ширина экрана
        h = self.winfo_screenheight() // 2 - 300  # высота экрана

        self.geometry('600x600 {} {}'.format(w, h))

        self.title('Curves')
        self.resizable(width=False, height=False)
        self['bg'] = '#7be8cf'

        Label(self, text='What are u looking for?', font=('Comic Sans MS', 20),
                       fg='#3d3d42', bg='#7be8cf').pack()
  

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

1. command = self.curves() должно быть command = self.curves , и вы также можете сказать в update_pic() self.img_but.image = self.img

2. @CoolCloud если я скажу, self.img_but.image = self.img тогда я получу следующую ошибку: AttributeError: 'Noise' object has no attribute 'img_but'. И использование command = self.curves не помогло. Я все еще открываю это окно перед нажатием кнопки.

3. я на самом деле попросил удалить () из метода и что с self.img_but[image] = self.img не так?

4. я не часто использую ООП, поэтому я не знаю, в чем проблема с атрибутами, но попробуйте img_but.image = self.img вместо self.img_but.image = self.img , и это также должно быть command=lambda: self.update_pic(pic)

5. @CoolCloud сначала я получаю Unresolved reference 'image' and then the same mistake ошибку атрибута: у объекта ‘Noise’ нет атрибута ‘img_but»

Ответ №1:

Команды не должны вызывать функции напрямую — вместо этого они должны называть функцию, которая будет вызываться при активации.

Попробуйте заменить это: command=self.update_pic(pic)

С помощью этого: command = lambda pic=pic: self.update_pic(pic)

И это: command = self.curves()

С помощью этого: command = self.curves

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

1. Да, это работает. Теперь другое окно не открывается раньше времени. Но как насчет изображения? Как его обновить?

2. Что ж, мне было бы легче протестировать эту часть, если бы я мог видеть полный код… Но, может быть, попробуйте добавить self.img_but = Button(self, image=self.img, command=self.curves) в конце update_pic функции, а затем использовать .update_idletasks или .update методы tkinter.Tk() объекта.

3. .update и .update_idletasks не сработало. Но размещение одной кнопки над другой работает))) self.img_but = Button(self, image=self.img, command=self.curves).place(x=150, y=300) добавление этого в конце update_pic

4. Отлично! Тогда я буду признателен, если вы выберете мой ответ. Вы даже можете отредактировать его, чтобы включить найденное вами решение, в интересах других в будущем 🙂 @EugeneKartashev