Анимация кнопки в tkinter
В общем делаю небольшую игру на tkinter чисто для опыта в написании кода, но вот завис на том, что не могу сделать нормальную анимацию для кнопки. Есть кнопка, которая сделана в виде картинки. После нажатия на нее, функция start_btn_anim делает свое дело и спрайт кнопки меняется на "вдавленную". Но при этом, дальше кнопка так и остается вдавленной, а я бы хотел, что бы она возвращалась к исходному положению. Помогите, кто знает. Какие-то еще профессиональные правки в коде тоже было бы классно почитать, я лишь новичок.
Вот код самой игры:
import tkinter as tk
from tkinter import *
from tkinter import ttk
from tkinter import Tk, Button
import PIL
from PIL import ImageTk
#---MAIN MENU---#
class Main_menu(tk.Tk):
def __init__(self):
super().__init__()
#Стили для всего текста в главном меню#
self.lbl_style = ttk.Style()
self.lbl_style.configure("TLabel",
font = ("KenVector Future Thin", 80, "bold"))
#-------------------------------------#
#ВИДЖЕТЫ И ИХ РАЗМЕЩЕНИЕ#
self.logo = ttk.Label(self,
text = "SFS") #Логотип#
self.logo.place(relx=.505,
rely=.25,
anchor="n")
self.version = ttk.Label(self,
text = "v0.0.1",
font = ("KenVector Future Thin", 12)) #Версия#
self.version.place(x = 0,
y = 0)
self.start_btn_sprite = PhotoImage(file = r"C:\Users\Вадим\Desktop\игра\sprites\PNG\grey_button01.png")
self.pressed_start_btn_sprite = PhotoImage(file = r"C:\Users\Вадим\Desktop\игра\sprites\PNG\grey_button02.png")
self.start_btn = Button(self,
text = "NEW GAME",
image = self.start_btn_sprite)
self.start_btn["border"] = "0"
def start_btn_anim(event):
self.start_btn.configure(image = self.pressed_start_btn_sprite)
self.start_btn.bind('<Button-1>', start_btn_anim)
self.start_btn.place(relx=.5,
rely=.4,
anchor="n")
self.options_btn = Button(self,
text = "OPTIONS",
image = self.start_btn_sprite)
self.options_btn["border"] = "0"
self.options_btn.place(relx=.5,
rely=.45,
anchor="n")
self.exit_btn = Button(self,
text = "EXIT",
image = self.start_btn_sprite,
command = self.quit)
self.exit_btn["border"] = "0"
self.exit_btn.place(relx=.5,
rely=.5,
anchor="n")
#-----------------------#
if __name__ == "__main__":
main_menu = Main_menu()
main_menu.geometry("1080x720")
main_menu.resizable(height = False, width = False)
main_menu.attributes('-fullscreen', True)
main_menu.overrideredirect(True)
main_menu.mainloop()
#---------------#
Ответы (1 шт):
Для обработки нажатия кнопки мышью нужно использовать параметр command, а не bind. Привязка через bind к событию клика мыши на кнопке приводит к эффекту "залипания" кнопки.
Варианты исправления:
# 1 вариант - изменения command через метод config
self.start_btn = Button(self,
text = "NEW GAME",
image = self.start_btn_sprite)
self.start_btn["border"] = "0"
def start_btn_anim(event):
self.start_btn.configure(image = self.pressed_start_btn_sprite)
self.start_btn.config(command=start_btn_anim)
# 2 вариант - указание command сразу при создании
def start_btn_anim(event):
self.start_btn.configure(image = self.pressed_start_btn_sprite)
self.start_btn = Button(self,
text = "NEW GAME",
image = self.start_btn_sprite
command=start_btn_anim)
self.start_btn["border"] = "0"
По самому коду особых комментариев нет, поэтому по стилю кода:
- По pep8 классы нужно называть с большой буквы каждое слово без разделения слов подчеркиваниями:
MainMenu - Выше и ниже класса или отдельной функции должно быть по две пустых строки (опять же, по pep8: см. Blank lines). У вас сразу выше и ниже класса идут отделяющие комментарии. Комментарий "MAIN MENU" перед классом
Main_menu- мягко говоря избыточный) - Отступы при переносе параметров функций на другую строку. Тут вот такой вариант правильный (с точки зрения pep8):
self.version = ttk.Label(self,
text="v0.0.1",
font=("KenVector Future Thin", 12))
только пробелов слева и справа от "равно" тут не должно быть (когда это передача параметров или указание значений по умолчанию для парамеров функции, при условии, что нет аннотации кода) - см. pep8 - Other Recommendation начиная со слов "Don’t use spaces around the = sign".
Вот такой вариант уже не правильный (все параметры визуально должны начинаться на одном уровне):
self.start_btn = Button(self,
text = "NEW GAME",
image = self.start_btn_sprite
command=start_btn_anim)
Правильно было бы так быть так:
self.start_btn = Button(self,
text="NEW GAME",
image=self.start_btn_sprite
command=start_btn_anim)
Я предпочитаю такой стиль:
self.start_btn = Button(
self,
text="NEW GAME",
image=self.start_btn_sprite
command=start_btn_anim
)
- это соответствует pep8, код становится не таким широким, не нужно каждый раз поправлять отступы, когда переименовываешь переменную, плюс все такие вызовы выглядят единообразно, с одинаковым отступом слева у параметров.
В принципе, если работаете в PyCharm, то он вам все несоответствия как предупреждения подчеркнет.
Также можно использовать какой-нибудь форматтер, например black (описание стиля), который весь код по своим понятия прекрасного отформатирует (black и PyCharm не во всем между собой согласны, но кому-то одному придется уступить).