为什么淡入淡出动画不起作用但淡出动画起作用?
Why isn't the fade in animation working but the fade out animation works?
我是 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
window
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 解释器并创建一个根 window。然后它控制它的不透明度属性淡入。之后,一个 Button 小部件被放置在具有这些属性的根 window 上:
- 文本'fade exit'写在小部件的顶部
- 它等待鼠标点击,然后控制根 window 的不透明度属性淡出。
最后,代替了
while True:
root.update_idletasks()
root.update()
您可能会注意到 'fade in' 按钮是在您的根目录 window 未更新时创建的。这就是您无法看到实际淡入的原因。
解决方案 1. 在每次淡入样本后更新根 window:
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
方法。查看迈克尔的回答。
我是 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
window 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 解释器并创建一个根 window。然后它控制它的不透明度属性淡入。之后,一个 Button 小部件被放置在具有这些属性的根 window 上:
- 文本'fade exit'写在小部件的顶部
- 它等待鼠标点击,然后控制根 window 的不透明度属性淡出。
最后,
while True:
root.update_idletasks()
root.update()
您可能会注意到 'fade in' 按钮是在您的根目录 window 未更新时创建的。这就是您无法看到实际淡入的原因。
解决方案 1. 在每次淡入样本后更新根 window:
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
方法。查看迈克尔的回答。