|I l@ve RuBoard|
9.6 Embedding Inline GIFs Using Tkinter
Credit: Brent Burley
A lively Tkinter GUI can include many small images. However, you probably shouldn't require that a small GIF file be present for each of these; ensuring the presence of many small files is a bother, and if they're missing, your GUI may be unusable or look wrong. Fortunately, you can construct Tkinter PhotoImage objects with inline data. It's easy to convert a GIF to inline form as Python source code:
import base64 print "icon='''\\\n" + base64.encodestring(open("icon.gif").read( )) + "'''"
You can then split the result into lines of reasonable length:
icon='''R0lGODdhFQAVAPMAAAQ2PESapISCBASCBMTCxPxmNCQiJJya/ISChGRmzPz+/PxmzDQyZ DQyZDQyZDQyZCwAAAAAFQAVAAAElJDISau9Vh2WMD0gqHHelJwnsXVloqDd2hrMm8pYYiSHYfMMRm 53ULlQHGFFx1MZCciUiVOsPmEkKNVp3UBhJ4Ohy1UxerSgJGZMMBbcBACQlVhRiHvaUsXHgywTdyc LdxyB gm1vcTyIZW4MeU6NgQEBXEGRcQcIlwQIAwEHoioCAgWmCZ0Iq5+hA6wIpqislgGhthEAOw== '''
and use it in Tkinter:
import Tkinter root = Tkinter.Tk( ) iconImage = Tkinter.PhotoImage(master=root, data=icon) Tkinter.Button(image=iconImage).pack( )
The basic technique is to encode the GIF with the standard Python module base64 and store the results as a string literal in the Python code, which will be passed to Tkinter's PhotoImage. The current release of PhotoImage supports GIF and PPM, but inline data is supported only for GIF. You can use file='filename', instead of data=string, for either GIF or PPM.
You must keep a reference to the PhotoImage object yourself; it is not kept by the Tkinter widget. If you pass it to Button and forget it, you will become very frustrated! Here's an easy workaround for this minor annoyance:
def makeImageWidget(icondata, *args, **kwds): if args: klass = args.pop(0) else: klass = Tkinter.Button class Widget(klass): def _ _init_ _(self, image, *args, **kwds): kwds['image']=image klass._ _init_ _(self, args, kwds) self._ _image = image return Widget(Tkinter.PhotoImage(data=icondata), *args, **kwds)
Using this, the equivalent of the example in the recipe becomes:
The master argument on PhotoImage is optional; it defaults to the default application window. If you create a new application window (by calling Tk again), you will need to create your images in that context and supply the master argument, so the makeImageWidget function would need to be updated to let you optionally pass the master argument to the PhotoImage constructor. However, most applications do not require this.
9.6.4 See Also
Information about Tkinter can be obtained from a variety of sources, such as Pythonware's An Introduction to Tkinter, by Fredrik Lundh (http://www.pythonware.com/library), New Mexico Tech's Tkinter reference (http://www.nmt.edu/tcc/help/lang/python/docs.html), and various books.
|I l@ve RuBoard|