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

#python #tkinter

Вопрос:

У меня есть два изображения для одной кнопки, а также я создал кнопки с изображениями. Я хотел бы изменить изображение кнопки всякий раз, когда я впервые нажимаю на нее. Например, когда я нажимаю кнопку, я хочу, чтобы изображение кнопки изменило «Незамеченное изображение» на «Щелкнутое изображение».

Я не смог найти ни одного похожего вопроса в stackoverflow.

 from tkinter import *


class Example(Frame):

    def __init__(self, tk=None):
        super().__init__()
        self.tk = tk
        self.init_ui()

    def init_ui(self):

        self.photoTodo = PhotoImage(file="./Images/TodoUnClicked.png")
        Button(self.tk, image=self.photoTodo).pack(side=LEFT)
        self.photoStayFocussed = PhotoImage(file="./Images/StayFoccusedUnClicked.png")
        Button(self.tk, image=self.photoStayFocussed).pack(side=RIGHT)


def main():

    root = Tk()
    root.configure(bg='white')
    ex = Example(root)
    root.title('')
    root.iconbitmap('./Images/empty.ico')
    root.geometry("400x100 300 300")
    root.mainloop()


if __name__ == '__main__':
    main()
 

Ответ №1:

Вы можете сделать это с помощью пользовательского класса кнопок.

 class ImageButton(Button):
    def __init__(self, master, image1, image2, *args, **kwargs):
        self.unclickedImage = PhotoImage(file = image1)
        self.clickedImage = PhotoImage(file = image2)
        super().__init__(master, *args, image = self.unclickedImage, **kwargs)
        self.toggleState = 1
        self.bind("<Button-1>", self.clickFunction)
    def clickFunction(self, event = None):
        if self.cget("state") != "disabled": #Ignore click if button is disabled
            self.toggleState *= -1
            if self.toggleState == -1:
                self.config(image = self.clickedImage)
            else:
                self.config(image = self.unclickedImage)
 

Это использует мастер виджета и первый и второй пути к изображению в качестве аргументов, создает PhotoImage объекты, а затем создает экземпляр кнопки с незащищенным изображением.
Существует привязка к <Button-1> , которая является щелчком левой кнопкой мыши, и это изменяет изображение при нажатии кнопки. toggleState Переменная отслеживает отображение текущего изображения, поэтому при нажатии кнопки отображается противоположное изображение.
Вы можете включить это в свою текущую программу следующим образом:

 from tkinter import *

class ImageButton(Button):
    def __init__(self, master, image1, image2, *args, **kwargs):
        self.unclickedImage = PhotoImage(file = image1)
        self.clickedImage = PhotoImage(file = image2)
        super().__init__(master, *args, image = self.unclickedImage, **kwargs)
        self.toggleState = 1
        self.bind("<Button-1>", self.clickFunction)
    def clickFunction(self, event = None):
        if self.cget("state") != "disabled": #Ignore click if button is disabled
            self.toggleState *= -1
            if self.toggleState == -1:
                self.config(image = self.clickedImage)
            else:
                self.config(image = self.unclickedImage)

class Example(Frame):

    def __init__(self, master, *args, **kwargs):
        super().__init__(master, *args, **kwargs)
        self.init_ui()

    def init_ui(self):
        ImageButton(self, "./Images/TodoUnClicked.png", "./Images/TodoClicked.png").pack(side=LEFT)
        ImageButton(self, "./Images/StayFoccusedUnClicked.png", "./Images/StayFoccusedClicked.png").pack(side=RIGHT)


def main():

    root = Tk()
    root.configure(bg='white')
    ex = Example(root)
    ex.pack(fill = "both", expand = True)
    root.title('')
    root.geometry("400x100 300 300")
    root.mainloop()


if __name__ == '__main__':
    main()
 

Обратите внимание, что я также исправил ваш Example класс, так как вы использовали его не совсем правильно. Когда вы наследуете объект tkinter, вы передаете его ведущему super().__init__ , а затем используете self в качестве родителя дочерних объектов.

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

1. почему бы вам не использовать self.config(command=self.clickFunction) вместо self.bind("<Button-1>", self.clickFunction) этого ?

2. Они могут захотеть передать команду кнопке, и это переопределит ее, в то время как привязка не будет.

3. ну, это выполнимо даже тогда, но это проще, за исключением того, что вы, вероятно, захотите также добавить проверку состояния кнопки, чтобы не вызывать функцию, когда кнопка отключена ( if self.cget('state') == 'disabled': return в начале clickFunction )

4. Хороший Ответ.