我如何停止闪烁在我的透明开机画面在Tkinter



使用我在网上找到的一些修改过的代码来创建一个通用的Tkinter启动屏幕,我试着用。png创建一个透明的启动屏幕。我知道这段代码只适用于Windows,我对此很满意。

然而,我注意到在屏幕上绘制图像时存在闪烁(画布区域在绘制图像之前是黑色的)。我不太了解它,但我怀疑它必须做一些缓冲后的图像谷歌搜索和阅读。我还看到canvas支持双缓冲所以闪烁不应该发生所以可能是Top Level widget之类的。

在任何情况下,有任何解决办法吗?我真的很想继续使用Tkinter,如果不能摆脱闪烁,那将是一个巨大的失望。下面是我使用的代码:

from Tkinter import *
import ttk
from PIL import Image, ImageTk
import time
class Splash:
    def __init__(self, root, filename, wait):
        self.__root = root
        #To use .pngs or .jpgs instead of just .bmps and .gifs, PIL is needed
        self.__file = ImageTk.PhotoImage(Image.open(filename))
        self.__wait = wait + time.clock()
    def __enter__(self):
        # Hide the root while it is built.
        self.__root.withdraw()
        # Create components of splash screen.
        window = Toplevel(self.__root)
        #Set splash window bg to transparent
        window.attributes('-transparent', '#FFFFFE')
        #Set canvas bg to transparent
        canvas = Canvas(window,bg="#FFFFFE")
        splash = self.__file
        # Get the screen's width and height.
        scrW = window.winfo_screenwidth()
        scrH = window.winfo_screenheight()
        # Get the images's width and height.
        imgW = splash.width()
        imgH = splash.height()
        # Compute positioning for splash screen.
        Xpos = (scrW - imgW) // 2
        Ypos = (scrH - imgH) // 2
        # Configure the window showing the logo.
        window.overrideredirect(True)
        window.geometry('+{}+{}'.format(Xpos, Ypos))
        # Setup canvas on which image is drawn.
        canvas.configure(width=imgW, height=imgH, highlightthickness=0)
        canvas.pack()
        # Show the splash screen on the monitor.
        canvas.create_image(imgW // 2, imgH // 2, image=splash)
        window.update()
        # Save the variables for later cleanup.
        self.__window = window
        self.__canvas = canvas
        self.__splash = splash
    def __exit__(self, exc_type, exc_val, exc_tb):
        # Ensure that required time has passed.
        now = time.clock()
        if now < self.__wait:
            time.sleep(self.__wait - now)
        # Free used resources in reverse order.
        del self.__splash
        self.__canvas.destroy()
        self.__window.destroy()
        # Give control back to the root program.
        self.__root.update_idletasks()
        self.__root.deiconify()
 if __name__ == '__main__':
 #thread2 = myLazyDoStuffThread()
 root = Tk()
 with Splash(root,'splash.png',3):
      myprog = ApplyGUIAndOtherThings(root)#,thread2)
 root.mainloop()

您应该遵循的经验法则是永远不要在GUI中调用sleep。它完全按照它说的做,它使你的整个应用程序进入睡眠状态。这意味着GUI无法重新绘制自己,这很可能是导致闪烁的原因。

如果您希望在一段时间后销毁窗口,请使用after方法。例如:

delta = (self.__wait - now) * 1000
self.after(delta, self.close)

你需要定义self。关闭以破坏窗户。

如果你喜欢的话,这给了你一个添加一点"淡出"效果的机会。你可以检查闪屏的alpha值是否低于某个阈值(比如10%),然后销毁它。如果不是,将alpha值降低10%,并在100毫秒后再次调用该函数

最新更新