2013-05-30 192 views
2

使用我在网上找到的一些修改后的代码来创建一个普通的Tkinter启动画面,我试图用.png创建一个透明的启动画面。我知道这个代码只能在Windows上工作,我很好。如何在Tkinter的透明闪屏中停止闪烁?

但是,我注意到当它在屏幕上绘制时,图像闪烁(画布区域在绘制图像之前是黑色的)。我对此不甚了解,但我怀疑在Google和Google阅读之后,必须对图像进行缓冲处理。我还看到,画布支持双缓冲,所以闪烁不应该发生,所以也许它是顶层部件或其他东西。

在任何情况下,是否有任何修复?我真的很想继续使用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() 
+0

'-transparent'不适用于我,但'-alpha'可以。 – User

回答

1

你应该遵循的经验法则是永远不要在GUI中拨打sleep的电话。它确实如它所说,它会导致你的整个应用程序进入睡眠状态。这意味着GUI无法重绘,并且可能是闪烁的原因。

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

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

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

如果您愿意,这可以让您有机会添加一点“淡化”效果。您可以通过检查启动画面的alpha是否低于某个阈值(比如10%)并将其销毁来做到这一点。如果不是,则将alpha减少10%,并在100 ms内再次调用该函数。