This class provides a very simple and clean way to produce a spash screen for any Tkinter application. It requires Python 2.5 or later.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
from __future__ import with_statement # <-- Python 2.5 ONLY import Tix import time class SplashScreen( object ): def __init__( self, tkRoot, imageFilename, minSplashTime=0 ): self._root = tkRoot self._image = Tix.PhotoImage( file=image ) self._splash = None self._minSplashTime = time.time() + minSplashTime def __enter__( self ): # Remove the app window from the display self._root.withdraw( ) # Calculate the geometry to center the splash image scrnWt = self._root.winfo_screenwidth( ) scrnHt = self._root.winfo_screenheight( ) imgWt = self._image.width() imgHt = self._image.height() imgXPos = (scrnWt / 2) - (imgWt / 2) imgYPos = (scrnHt / 2) - (imgHt / 2) # Create the splash screen self._splash = Tix.Toplevel() self._splash.overrideredirect(1) self._splash.geometry( '+%d+%d' % (imgXPos, imgYPos) ) Tix.Label( self._splash, image=self._image, cursor='watch' ).pack( ) # Force Tk to draw the splash screen outside of mainloop() self._splash.update( ) def __exit__( self, exc_type, exc_value, traceback ): # Make sure the minimum splash time has elapsed timeNow = time.time() if timeNow < self._minSplashTime: time.sleep( self._minSplashTime - timeNow ) # Destroy the splash window self._splash.destroy( ) # Display the application window self._root.deiconify( ) #-------------------------------------------- # Now putting up splash screens is simple # Create the tkRoot window tkRoot = Tix.Tk( ) with SplashScreen( tkRoot, 'splashImage.jpg', 3.0 ): initializeMyApplication( ) buildTheGUI( tkRoot ) tkRoot.mainloop( )
I've struggled for a long time to design a splash screen solution that is both elegant and flexible. Before I knew it was possible to call update() outside of mainloop() to get widgets to display, I would setup a timer callback using after(). It was a very ugly solution. The use of update() and the introduction of the with statement made it possible to encapsulate a splash screen into an object which results in very clean code.
The best way to use this code is to insert the SplashScreen class definition into a module and import it into your application. Generally you want the splash screen up while you initialize you application. Therefore, ideally you will follow the usage that I outline above. That is, create the tk root window, then immedicately start a with statement creating the splash screen. The suite of statements in the body of the with statement can then do all your initialization and build your GUI. When the with statement exits the splash screen is destroyed and your next line of code is to enter the mainloop().
The third parameter to the SplashScreen constructor is optional. It's a minimal time in seconds to display the splash image.
In my example above I actually import Tix rather than Tkinter. This is because I use many of the Tix widgets in my own applications. Importing Tix gives me all the Tix widgets plus everything that I would have gotten if I had imported Tkinter explicitly.