4.3. Packing Demonstration Program
Prev | Chapter 4. Packing Widgets | Next

## 4.3. Packing Demonstration Program

Here is the code used to create the above images. It's commented fairly heavily so I hope you won't have any problems following it. Run it yourself and play with it.

        1	#!/usr/bin/env python
        2
        3	# example packbox.py
        4
        5	import pygtk
        6	pygtk.require('2.0')
        7	import gtk
        8	import sys, string
        9
       10	# Helper function that makes a new hbox filled with button-labels. Arguments
       11	# for the variables we're interested are passed in to this function.  We do
       12	# not show the box, but do show everything inside.
       13
       14	def make_box(homogeneous, spacing, expand, fill, padding):
       15
       16	    # Create a new hbox with the appropriate homogeneous
       17	    # and spacing settings
       18	    box = gtk.HBox(homogeneous, spacing)
       19
       20	    # Create a series of buttons with the appropriate settings
       21	    button = gtk.Button("box.pack")
       22	    box.pack_start(button, expand, fill, padding)
       23	    button.show()
       24
       25	    button = gtk.Button("(button,")
       26	    box.pack_start(button, expand, fill, padding)
       27	    button.show()
       28
       29	    # Create a button with the label depending on the value of
       30	    # expand.
       31	    if expand == True:
       32	        button = gtk.Button("True,")
       33	    else:
       34	        button = gtk.Button("False,")
       35
       36	    box.pack_start(button, expand, fill, padding)
       37	    button.show()
       38
       39	    # This is the same as the button creation for "expand"
       40	    # above, but uses the shorthand form.
       41	    button = gtk.Button(("False,", "True,")[fill==True])
       42	    box.pack_start(button, expand, fill, padding)
       43	    button.show()
       44
       45	    padstr = "%d)" % padding
       46
       47	    button = gtk.Button(padstr)
       48	    box.pack_start(button, expand, fill, padding)
       49	    button.show()
       50	    return box
       51
       52	class PackBox1:
       53	    def delete_event(self, widget, event, data=None):
       54	        gtk.main_quit()
       55	        return False
       56
       57	    def __init__(self, which):
       58
       59	        # Create our window
       60	        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
       61
       62	        # You should always remember to connect the delete_event signal
       63	        # to the main window. This is very important for proper intuitive
       64	        # behavior
       65	        self.window.connect("delete_event", self.delete_event)
       66	        self.window.set_border_width(10)
       67
       68	        # We create a vertical box (vbox) to pack the horizontal boxes into.
       69	        # This allows us to stack the horizontal boxes filled with buttons one
       70	        # on top of the other in this vbox.
       71	        box1 = gtk.VBox(False, 0)
       72
       73	        # which example to show. These correspond to the pictures above.
       74	        if which == 1:
       75	            # create a new label.
       76	            label = gtk.Label("HBox(False, 0)")
       77
       78	            # Align the label to the left side.  We'll discuss this method
       79	            # and others in the section on Widget Attributes.
       80	            label.set_alignment(0, 0)
       81
       82	            # Pack the label into the vertical box (vbox box1).  Remember that
       83	            # widgets added to a vbox will be packed one on top of the other in
       84	            # order.
       85	            box1.pack_start(label, False, False, 0)
       86
       87	            # Show the label
       88	            label.show()
       89
       90	            # Call our make box function - homogeneous = False, spacing = 0,
       91	            # expand = False, fill = False, padding = 0
       92	            box2 = make_box(False, 0, False, False, 0)
       93	            box1.pack_start(box2, False, False, 0)
       94	            box2.show()
       95
       96	            # Call our make box function - homogeneous = False, spacing = 0,
       97	            # expand = True, fill = False, padding = 0
       98	            box2 = make_box(False, 0, True, False, 0)
       99	            box1.pack_start(box2, False, False, 0)
      100	            box2.show()
      101
      102	            # Args are: homogeneous, spacing, expand, fill, padding
      103	            box2 = make_box(False, 0, True, True, 0)
      104	            box1.pack_start(box2, False, False, 0)
      105	            box2.show()
      106
      107	            # Creates a separator, we'll learn more about these later,
      108	            # but they are quite simple.
      109	            separator = gtk.HSeparator()
      110
      111	            # Pack the separator into the vbox. Remember each of these
      112	            # widgets is being packed into a vbox, so they'll be stacked
      113	            # vertically.
      114	            box1.pack_start(separator, False, True, 5)
      115	            separator.show()
      116
      117	            # Create another new label, and show it.
      118	            label = gtk.Label("HBox(True, 0)")
      119	            label.set_alignment(0, 0)
      120	            box1.pack_start(label, False, False, 0)
      121	            label.show()
      122
      123	            # Args are: homogeneous, spacing, expand, fill, padding
      124	            box2 = make_box(True, 0, True, False, 0)
      125	            box1.pack_start(box2, False, False, 0)
      126	            box2.show()
      127
      128	            # Args are: homogeneous, spacing, expand, fill, padding
      129	            box2 = make_box(True, 0, True, True, 0)
      130	            box1.pack_start(box2, False, False, 0)
      131	            box2.show()
      132
      133	            # Another new separator.
      134	            separator = gtk.HSeparator()
      135	            # The last 3 arguments to pack_start are:
      136	            # expand, fill, padding.
      137	            box1.pack_start(separator, False, True, 5)
      138	            separator.show()
      139	        elif which == 2:
      140	            # Create a new label, remember box1 is a vbox as created
      141	            # near the beginning of __init__()
      142	            label = gtk.Label("HBox(False, 10)")
      143	            label.set_alignment( 0, 0)
      144	            box1.pack_start(label, False, False, 0)
      145	            label.show()
      146
      147	            # Args are: homogeneous, spacing, expand, fill, padding
      148	            box2 = make_box(False, 10, True, False, 0)
      149	            box1.pack_start(box2, False, False, 0)
      150	            box2.show()
      151
      152	            # Args are: homogeneous, spacing, expand, fill, padding
      153	            box2 = make_box(False, 10, True, True, 0)
      154	            box1.pack_start(box2, False, False, 0)
      155	            box2.show()
      156
      157	            separator = gtk.HSeparator()
      158	            # The last 3 arguments to pack_start are:
      159	            # expand, fill, padding.
      160	            box1.pack_start(separator, False, True, 5)
      161	            separator.show()
      162
      163	            label = gtk.Label("HBox(False, 0)")
      164	            label.set_alignment(0, 0)
      165	            box1.pack_start(label, False, False, 0)
      166	            label.show()
      167
      168	            # Args are: homogeneous, spacing, expand, fill, padding
      169	            box2 = make_box(False, 0, True, False, 10)
      170	            box1.pack_start(box2, False, False, 0)
      171	            box2.show()
      172
      173	            # Args are: homogeneous, spacing, expand, fill, padding
      174	            box2 = make_box(False, 0, True, True, 10)
      175	            box1.pack_start(box2, False, False, 0)
      176	            box2.show()
      177
      178	            separator = gtk.HSeparator()
      179	            # The last 3 arguments to pack_start are:
      180	            # expand, fill, padding.
      181	            box1.pack_start(separator, False, True, 5)
      182	            separator.show()
      183
      184	        elif which == 3:
      185
      186	            # This demonstrates the ability to use pack_end() to
      187	            # right justify widgets. First, we create a new box as before.
      188	            box2 = make_box(False, 0, False, False, 0)
      189
      190	            # Create the label that will be put at the end.
      191	            label = gtk.Label("end")
      192	            # Pack it using pack_end(), so it is put on the right
      193	            # side of the hbox created in the make_box() call.
      194	            box2.pack_end(label, False, False, 0)
      195	            # Show the label.
      196	            label.show()
      197
      198	            # Pack box2 into box1
      199	            box1.pack_start(box2, False, False, 0)
      200	            box2.show()
      201
      202	            # A separator for the bottom.
      203	            separator = gtk.HSeparator()
      204
      205	            # This explicitly sets the separator to 400 pixels wide by 5
      206	            # pixels high. This is so the hbox we created will also be 400
      207	            # pixels wide, and the "end" label will be separated from the
      208	            # other labels in the hbox. Otherwise, all the widgets in the
      209	            # hbox would be packed as close together as possible.
      210	            separator.set_size_request(400, 5)
      211	            # pack the separator into the vbox (box1) created near the start
      212	            # of __init__()
      213	            box1.pack_start(separator, False, True, 5)
      214	            separator.show()
      215
      216	        # Create another new hbox.. remember we can use as many as we need!
      217	        quitbox = gtk.HBox(False, 0)
      218
      219	        # Our quit button.
      220	        button = gtk.Button("Quit")
      221
      222	        # Setup the signal to terminate the program when the button is clicked
      223	        button.connect("clicked", lambda w: gtk.main_quit())
      224	        # Pack the button into the quitbox.
      225	        # The last 3 arguments to pack_start are:
      226	        # expand, fill, padding.
      227	        quitbox.pack_start(button, True, False, 0)
      228	        # pack the quitbox into the vbox (box1)
      229	        box1.pack_start(quitbox, False, False, 0)
      230
      231	        # Pack the vbox (box1) which now contains all our widgets, into the
      232	        # main window.
      233	        self.window.add(box1)
      234
      235	        # And show everything left
      236	        button.show()
      237	        quitbox.show()
      238
      239	        box1.show()
      240	        # Showing the window last so everything pops up at once.
      241	        self.window.show()
      242
      243	def main():
      244	    # And of course, our main loop.
      245	    gtk.main()
      246	    # Control returns here when main_quit() is called
      247	    return 0
      248
      249	if __name__ =="__main__":
      250	    if len(sys.argv) != 2:
      251	        sys.stderr.write("usage: packbox.py num, where num is 1, 2, or 3.\n")
      252	        sys.exit(1)
      253	    PackBox1(string.atoi(sys.argv[1]))
      254	    main()

A brief tour of the packbox.py code starts with lines 14-50 which define a helper function `make_box`() that creates a horizontal box and populates it with buttons according to the specified parameters. A reference to the horizontal box is returned.

Lines 52-241 define the `PackBox1` class initialization method `__init__`() that creates a window and a child vertical box that is populated with a different widget arrangement depending on the argument passed to it. If a 1 is passed, lines 75-138 create a window displaying the five unique packing arrangements that are available when varying the homogeneous, expand and fill parameters. If a 2 is passed, lines 140-182 create a window displaying the various combinations of fill with spacing and padding. Finally, if a 3 is passed, lines 188-214 create a window displaying the use of the `pack_start`() method to left justify the buttons and `pack_end`() method to right justify a label. Lines 215-235 create a horizontal box containing a button that is packed into the vertical box. The button "clicked" signal is connected to the PyGTK `main_quit`() function to terminate the program.

Lines 250-252 check the command line arguments and exit the program using the `sys.exit`() function if there isn't exactly one argument. Line 253 creates a PackBox1 instance. Line 254 invokes the `main`() function to start the GTK event processing loop.

In this example program, the references to the various widgets (except the window) are not saved in the object instance attributes because they are not needed later.

Prev | Up | Next
4.2. Details of Boxes | Home | 4.4. Packing Using Tables