페이드 인 애니메이션은 작동하지 않지만 페이드 아웃 애니메이션은 작동하는 이유는 무엇입니까?
저는 파이썬을 처음 접했고 tkinter와 time 모듈을 사용하여 파이썬 에서 간단한 페이드 애니메이션을 만드는 방법에 대한 아이디어를 생각해 냈습니다 . 프로그램에 대해 두 가지 애니메이션을 정의했습니다. 하나는 페이드 인하 고 다른 하나는 페이드 아웃합니다. 페이드 아웃 애니메이션은 내가 원하는대로 완벽하게 작동하지만 페이드 인 애니메이션은 전혀 작동하지 않습니다. 프로그램은 while 루프가 끝날 때까지 거의 나타나지 않습니다. 내가 뭘 잘못하고 있거나 파이썬 tkinter에서 페이드 인 효과를 만드는 것이 불가능합니까? 내 코드 스 니펫은 다음과 같습니다.
from tkinter import *
import time
root = Tk()
transparency = 0
while transparency <= 1:
transparency += 0.1
root.wm_attributes("-alpha", transparency)
time.sleep(0.03)
def fade():
t = 1
while t > 0:
t -= 0.1
root.wm_attributes("-alpha", t)
time.sleep(0.03)
root.destroy()
btn = Button(root, text='fade exit', command=fade).pack()
root.mainloop()
답변
while
루프 및를 사용하는 대신 및 재귀를 time
사용하십시오 after(millis, function)
.
보너스 :
- 함수 인수를 사용하여 페이드 효과 및 동작을 사용자 정의하십시오.
- 이것은 루트의 업데이트를 차단하지 않습니다.
- 모든 것이 캡슐화되어 있습니다
- 이러한 기능은 모든
Toplevel
창에서 사용할 수 있습니다. applyFades
한 번의 통화로 모든 것을 관리
이러한 기능을에 반드시 첨부해야하는 경우 다음 과 같이 인수 Button
를 지정하면 됩니다..command
command=lambda: fadeOut(root)
window.py
''' Fade In
@window ~ the window to affect
@millis ~ the amount of milliseconds to wait before next recursion
@inc ~ the amount to increment alpha on each recursion
'''
def fadeIn(window, millis:int=50, inc:float=0.1):
alpha = float(window.attributes('-alpha')) + inc
window.attributes('-alpha', alpha)
if alpha < 1:
window.after(millis, lambda: fadeIn(window, millis, inc))
else:
window.attributes('-alpha', 1.0)
''' Fade Out
@window, @millis ~ see: Fade In
@dec ~ the amount to decrement alpha on each recursion
@destroy ~ True|False destroy the window when effect is complete
'''
def fadeOut(window, millis:int=50, dec:float=0.1, destroy:bool=True):
alpha = float(window.attributes('-alpha')) - dec
window.attributes('-alpha', alpha)
if alpha > 0:
window.after(millis, lambda: fadeOut(window, millis, dec, destroy))
else:
window.attributes('-alpha', 0.0)
if destroy:
window.destroy()
''' Assign All Fades In One Call
@window, @millis, @inc ~ see: Fade In
@dec, @destroy ~ see: Fade Out
@close ~ True|False add fadeOut effect to window close button
'''
def applyFades(window, millis:int=50, inc:float=0.1, dec:float=0.1, destroy:bool=True, close:bool=True):
window.attributes('-alpha', 0.0)
window.after(millis, lambda: fadeIn(window, millis, inc))
if close:
window.protocol("WM_DELETE_WINDOW", lambda: fadeOut(window, millis, dec, destroy))
main.py
import tkinter as tk
import window as win
root = tk.Tk()
win.applyFades(root)
root.mainloop()
스크립트가 무엇을하는지 봅시다. 처음에는 root = Tk()tcl / tk 인터프리터를 시작하고 루트 창을 만드는 할당됩니다. 그런 다음 페이드 인 할 불투명도 속성을 제어합니다. 그 후 다음 속성을 가진 루트 창에 Button 위젯이 배치됩니다.
- 위젯 상단에 '페이드 종료'라는 텍스트가 기록됩니다.
- 마우스 클릭을 기다렸다가 루트 창의 불투명도 속성을 제어 한 후 페이드 아웃합니다.
마지막으로, root.mainloop()대체를위한이다
while True:
root.update_idletasks()
root.update()
루트 창이 업데이트되지 않는 순간에 '페이드 인'버튼이 생성되고 있다는 점에 주목할 수 있습니다. 이것이 실제 페이드 인을 볼 수없는 이유입니다.
솔루션 1. 페이드 인의 각 샘플 후 루트 창 업데이트 :
from tkinter import *
import time
def fade():
t = 1
while t > 0:
t -= 0.1
root.wm_attributes("-alpha", t)
time.sleep(0.03)
root.destroy()
root = Tk()
transparency = 0
btn = Button(root, text='fade in', command=fade)
btn.pack()
while transparency <= 1:
transparency += 0.1
root.wm_attributes("-alpha", transparency)
root.update_idletasks()
root.update()
time.sleep(0.03)
btn.configure(text='fade exit') #I guess no new button is needed and text should be replaced only
root.mainloop()
해결 방법 2. 사용 방법 과 tkinter
병용 하지 않는 것이 일반적 입니다. Michael의 대답을 확인하십시오.time
after