How to fade in/out on a Tkinter Frame
此问题表明您不能使用Tkinter的默认透明度来淡入和淡出使用窗口小部件。但是,有没有其他方法,使用PIL或其他方式,淡入淡出Tkinter中的小部件(或图片)? (即透明度可调)
答案 0 :(得分:1)
(希望)简单的答案:
#!python3
import tkinter as tk
from PIL import Image, ImageTk
import os
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("Image Fading")
self.label = tk.Label(self)
self.label.pack()
self.load_pictures()
self.fadetime = 1 # time between alpha channel changes in ms
self.fadestep = 5 # change to alpha channel
self.curstep = 0 # the current step through the transparency
self.im = None # to hold the raw picture
self.photo = None # to hold the tk compatible picture
self.after(self.fadetime, self.fade_in)
def fade_in(self):
if not self.im:
self.load_picture()
alpha = min(self.curstep * self.fadestep, 255) # clamp to 255 maximum
self.im.putalpha(alpha)
self.photo = ImageTk.PhotoImage(self.im)
self.label.configure(image=self.photo)
self.curstep += 1
print('fade in: %i' % alpha)
if alpha == 255:
self.curstep = 0
self.after(3000, self.fade_out) # wait three seconds then fade out
else:
self.after(self.fadetime, self.fade_in)
def fade_out(self):
alpha = max(255 - self.curstep * self.fadestep, 0) # clamp to 0 minimum
self.im.putalpha(alpha)
self.photo = ImageTk.PhotoImage(self.im)
self.label.configure(image=self.photo)
self.curstep += 1
print('fade out: %i' % alpha)
if alpha == 0:
self.curstep = 0
self.im = None
self.index += 1 # to use next picture
if self.index >= len(self.filenames):
self.index = 0
self.after(3000, self.fade_in) # wait three seconds then load next picture
else:
self.after(self.fadetime, self.fade_out)
def load_picture(self):
while True:
file = open(self.filenames[self.index], mode='rb')
try: # if errors opening file as image, ignore and try next one
self.im = Image.open(file) # this is a lazy operation and only reads image header
self.im.load() # force image load here
file.close() # close the file
print('loaded: %s' % self.filenames[self.index])
break
except:
file.close()
self.index += 1
if self.index >= len(self.filenames):
self.index = 0
def load_pictures(self):
self.filenames = []
for file in os.listdir():
if file.rsplit('.', 1)[-1] not in ['db', 'py', 'pyw']:
self.filenames.append(file)
self.index = -1
if __name__ == '__main__':
app = App()
app.mainloop()
这假设你想要将每个图像淡出然后是下一个图像,而不是从一个图像直接淡化到另一个图像。
请注意,尽管以最简单的方式(使用putalpha
)执行此类淡入/淡出操作仍然是cpu密集型的,因为每次尝试都会转换为ImageTk
实例。
这就是为什么我把变量用于alpha步长和时间来控制需要调用它的次数。
如果我的假设是错误的并且您需要从一个直线淡入到下一个,那么它会更加密集,因为您需要在将Alpha通道应用到每个图像后将图像“混合”在一起,然后将结果转换为ImageTk
实例