Chapter 6. The Button Widget

Table of Contents
6.1. Normal Buttons
6.2. Toggle Buttons
6.3. Check Buttons
6.4. Radio Buttons

6.1. Normal Buttons

We've almost seen all there is to see of the button widget. It's pretty simple. You can use the GtkButton() to create a button with a label by passing a string parameter, or to create a blank button by not specifying a label string. It's then up to you to pack a label or pixmap into this new button. To do this, create a new box, and then pack your objects into this box using the usual pack_start(), and then use add() to pack the box into the button.

The buttons.py program provides an example of using GtkButton() to create a button with a picture and a label in it. I've broken up the code to create a box from the rest so you can use it in your programs. There are further examples of using pixmaps later in the tutorial. Figure 6.1 shows the window containing a button with both a pixmap and a label:

Figure 6.1 Button with Pixmap and Label

The source code for the buttons.py program is:
 
    1   #!/usr/bin/env python
    2   
    3   # example-start buttons buttons.c
    4   
    5   import gtk
    6   
    7   # Create a new hbox with an image and a label packed into it
    8   # and return the box.
    9   
   10   def xpm_label_box(parent, xpm_filename, label_text):
   11       # Create box for xpm and label
   12       box1 = gtk.GtkHBox(gtk.FALSE, 0)
   13       box1.set_border_width(2)
   14   
   15       # Get the style of the button to get the
   16       # background color.
   17       style = parent.get_style()
   18   
   19       # Now on to the xpm stuff
   20       pixmap, mask = gtk.create_pixmap_from_xpm(parent.get_window(),
   21                                                 style.bg[gtk.STATE_NORMAL],
   22                                                 xpm_filename)
   23       pixmapwid = gtk.GtkPixmap(pixmap, mask)
   24   
   25       # Create a label for the button
   26       label = gtk.GtkLabel(label_text)
   27   
   28       # Pack the pixmap and label into the box
   29       box1.pack_start(pixmapwid, gtk.FALSE, gtk.FALSE, 3)
   30       box1.pack_start(label, gtk.FALSE, gtk.FALSE, 3)
   31   
   32       pixmapwid.show()
   33       label.show()
   34       return box1
   35   
   36   class Buttons:
   37       # Our usual callback method
   38       def callback(self, widget, data=None):
   39           print "Hello again - %s was pressed" % data
   40   
   41       def __init__(self):
   42           # Create a new window
   43           self.window = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
   44   
   45           self.window.set_title("Pixmap'd Buttons!")
   46   
   47           # It's a good idea to do this for all windows.
   48           self.window.connect("destroy", gtk.mainquit)
   49           self.window.connect("delete_event", gtk.mainquit)
   50   
   51           # Sets the border width of the window.
   52           self.window.set_border_width(10)
   53           self.window.realize()
   54   
   55           # Create a new button
   56           button = gtk.GtkButton()
   57   
   58           # Connect the "clicked" signal of the button to our callback
   59           button.connect("clicked", self.callback, "cool button")
   60   
   61           # This calls our box creating function
   62           box1 = xpm_label_box(self.window, "info.xpm", "cool button")
   63   
   64           # Pack and show all our widgets
   65           button.add(box1)
   66   
   67           box1.show()
   68           button.show()
   69   
   70           self.window.add(button)
   71           self.window.show()
   72   
   73   def main():
   74       gtk.mainloop()
   75       return 0     
   76   
   77   if __name__ == "__main__":
   78       Buttons()
   79       main()

Lines 10-34 define the xpm_label_box() helper function which creates a horizontal box with a border width of 2 (lines 12-13), populates it with a pixmap (lines 20-23) and a label (line 26).

Lines 36-71 defines the Buttons class. Lines 43-71 define the instance initialization method which creates a window (line 43), sets the title (line 45), connects the "delete_event" and "destroy" signals (lines 48-49) and realizes the window (line 53). Line 56 creates the button without a label. It's "clicked" signal gets connected to the callback() method in line 59. The xpm_label_box() function is called in line 62 to create the pixmap and label to put in the button in line 65.

The xpm_label_box() function could be used to pack xpm's and labels into any widget that can be a container.

Notice in xpm_label_box() how there is a call to the get_style() method. Every widget has a "style", consisting of foreground and background colors for a variety of situations, font selection, and other graphics data relevant to a widget. These style values are defaulted in each widget, and are required by many PyGTK function calls, such as create_pixmap_from_xpm(), which here is given the "normal" background color. The style data of widgets may be customized, using GTK's rc files. More information on styles can be found in the Widget Styles section.

Also notice the call to the realize() method after setting the window's border width. This method creates the X windows related to the widget. The method is automatically called when you invoke the show() method for a widget, and so has not been shown in earlier examples. But the call to create_pixmap_from_xpm() requires that its window argument refer to a real X window, so it is necessary to realize the widget before creating the pixmap

The Button widget has the following signals: