问题描述
我是python的新手,我想到了如何使用tkinter和时间模块在 python中制作简单的淡入淡出动画的想法。我为程序定义了两个动画:一个动画淡入,另一个动画淡出。淡入淡出动画可以完美完美地实现我想要的效果,但是,淡入淡出动画根本不起作用。在while循环完成之前,该程序几乎不会显示。我是在做错什么还是在python 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,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,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,inc:float=0.1,destroy:bool=True,close:bool=True):
window.attributes('-alpha',0.0)
window.after(millis,inc))
if close:
window.protocol("WM_DELETE_WINDOW",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
与time
结合使用,而使用after
方法。查看迈克尔的答案。