Section 8.10. Customizing Widgets with Classes


8.10. Customizing Widgets with Classes

You don't have to use OOP in Tkinter scripts, but it can definitely help. As we just saw, Tkinter GUIs are built up as class-instance object trees. Here's another way Python's OOP features can be applied to GUI models: specializing widgets by inheritance. Example 8-18 builds the window in Figure 8-21.

Figure 8-21. A button subclass in action


Example 8-18. PP3E\Gui\Intro\gui5.py

 from Tkinter import * class HelloButton(Button):     def _ _init_ _(self, parent=None, **config):         # add callback method         Button._ _init_ _(self, parent, config)          # and pack myself         self.pack( )         self.config(command=self.callback)     def callback(self):                                # default press action         print 'Goodbye world...'                       # replace in subclasses         self.quit( ) if _ _name_ _ == '_ _main_ _':     HelloButton(text='Hello subclass world').mainloop( ) 

This example isn't anything special to look at: it just displays a single button that, when pressed, prints a message and exits. But this time, it is a button widget we created on our own. The HelloButton class inherits everything from the Tkinter Button class, but adds a callback method and constructor logic to set the command option to self.callback, a bound method of the instance. When the button is pressed this time, the new widget class's callback method, not a simple function, is invoked.

The **config argument here is assigned unmatched keyword arguments; they're passed along to the Button constructor. We met the config widget method called in HelloButton's constructor earlier; it is just an alternative way to pass configuration options after the fact (instead of passing constructor arguments).

So what's the point of subclassing widgets like this? It allows widgets to be configured by subclassing instead of by passing in options. HelloButton is a true button; we pass in configuration options as usual when one is made. But we can also specify callback handlers by overriding the callback method in subclasses, as shown in Example 8-19.

Example 8-19. PP3E\Gui\Intro\gui5b.py

 from gui5 import HelloButton class MyButton(HelloButton):        # subclass HelloButton     def callback(self):             # redefine press-handler method         print "Ignoring press!..." if _ _name_ _ == '_ _main_ _':     MyButton(None, text='Hello subclass world').mainloop( ) 

Instead of exiting, this MyButton button, when pressed, prints to stdout and stays up. Here is its standard output after being pressed a few times:

 C:\PP2ndEd\examples\PP3E\Gui\Intro>python gui5b.py Ignoring press!... Ignoring press!... Ignoring press!... Ignoring press!... 

Whether it's simpler to customize widgets by subclassing or passing in options is probably a matter of taste. But the point to notice is that Tk becomes truly object oriented in Python, just because Python is object oriented: we can specialize widget classes using normal class-based object-oriented techniques. The next example provides yet another way to arrange for specialization.




Programming Python
Programming Python
ISBN: 0596009259
EAN: 2147483647
Year: 2004
Pages: 270
Authors: Mark Lutz

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net