【问题标题】:How do I stop flickering in my transparent Splash screen in Tkinter?如何在 Tkinter 的透明启动画面中停止闪烁?
【发布时间】:2013-05-30 03:32:09
【问题描述】:

使用我在网上找到的一些修改过的代码来创建一个通用的 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()

【问题讨论】:

  • -transparent 对我不起作用,但 -alpha 可以。

标签: python canvas tkinter transparent splash-screen


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多