2

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

但是,我注意到在屏幕上绘制时图像会闪烁(画布区域在绘制图片之前是黑色的)。我不太了解它,但我怀疑它必须在谷歌搜索和阅读后对图像进行缓冲。我还读到画布支持双缓冲,所以不应该发生闪烁,所以可能是顶级小部件或其他东西。

无论如何,有什么解决办法吗?我真的很想继续为此使用 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()
4

1 回答 1

1

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

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

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

您需要定义 self.close 来销毁窗口。

如果您愿意,这使您有机会添加一点“渐隐”效果。您可以通过检查初始屏幕的 alpha 是否低于某个阈值(例如 10%)并销毁它来执行此操作。如果不是,则将 alpha 降低 10% 并在 100 毫秒内再次调用该函数。

于 2013-05-30T11:03:43.940 回答