python - 如何在 Tkinter 的透明启动画面中停止闪烁?

标签 python canvas tkinter transparent splash-screen

使用我在网上找到的一些用于创建通用 Tkinter 闪屏的修改代码,我尝试创建一个带有 .png 的透明闪屏之类的东西。我知道此代码仅适用于 Windows,对此我没有意见。

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

无论如何,有什么办法可以解决这个问题吗?我真的很想为此继续使用 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.close 来销毁窗口。

这使您有机会根据需要添加一点“淡出”效果。为此,您可以检查启动画面的 alpha 是否低于某个阈值(例如 10%)并将其销毁。如果不是,则将 alpha 降低 10% 并在 100 毫秒后再次调用该函数。

关于python - 如何在 Tkinter 的透明启动画面中停止闪烁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16827481/

相关文章:

python - 切片后订购 Django QuerySet

python - 在 numba 的 jitclass 中索引多维 numpy 数组

javascript - map : texture from new THREE. 纹理( Canvas )不起作用

Python:Tkinter TclError:无法调用 "image"命令

python - 如何解析具有 FIX 消息格式的平面文件(在 python 中)?

python - 在 LIbre Office Calc 中编写宏需要什么语言?

javascript - 3D 地球的网格系统

javascript - 在javascript中移动圆圈

python - 您如何找到小部件的唯一且恒定的 ID?

python - 鼠标悬停时如何更改行颜色? Tkinter TreeView