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.