By the way, I'm going through  http://www.gtk.org/tutorial and translating the 
examples from C to python, and sending them in to the maintainer.  Here's the 
ones I've done so far.

Chapter 3: base.py, hello.py
chapter 4: hello2.py
chapter 5: packbox.py

Still working on the second (table based) example in chapter 5...

Rob

-- 
penguicon.sf.net - A combination Linux Expo and Science Fiction Convention, 
May 2-4 2003 in Warren, Michigan. Tutorials, installfest, filk, masquerade...
#!/usr/bin/python

import gtk

win=gtk.Window()
win.show()
gtk.mainloop()
#!/usr/bin/python

import gtk

class hello:

  # The "hello" signal is sent when you click the button.

  def hello(self, obj):
    print "Hello World"

  # The "delete_event" signal is sent when they try to close the window.

  def delete_event(self, obj, event):
    # Return TRUE and nothing happens, return FALSE and a destroy_event gets
    # sent to the main window, which actually makes it go away.  This is
    # intended to allow you to stick in an "Are you sure?" type pop-up dialog.

    print "delete event occurred"
    return gtk.TRUE

  # The "kill -9" type callback.  Quit without a confirmation pop-up.

  def destroy(self, obj):
    gtk.mainquit()

  # The constructor function for the class

  def __init__(self):

    # We don't have to call an equivalent of gtk_init manually.  Importing
    # the gtk module did that for us as part of its setup.

    # Create a window.

    self.window=gtk.Window()

    # Let it know how to go away.

    self.window.connect("delete_event",self.delete_event)
    self.window.connect("destroy",self.destroy)

    # Give it a little padding around the edges.

    self.window.set_border_width(10)

    # Create a button.

    self.button=gtk.Button("Hello World!")

    # Install signal handlers on the button to provide appropriate behavior.

    self.button.connect("clicked",self.hello)
    self.button.connect("clicked",lambda a: self.window.destroy())

    # Put the button in the window.

    self.window.add(self.button)

    # make everything visible.

    self.button.show()
    self.window.show()

# If this module is being called directly rather than imported by another
# module...

if __name__ == "__main__":

  # Instantiate our dialog and loop dispatching events for it.

  hello()
  gtk.mainloop()
#!/usr/bin/python

import gtk

# Python specific note: I tried to make this example match the C example
# as closely as possible, but there were a couple of judgement calls:

# This is a class, and that means local variables and instance variables
# are different.  I made all the references to GTK widgets instance variables
# (so you can reach out and twiddle GUI elements easily long after
# instantiating them), but "button" was re-used for both buttons in the C
# example.  I changed it to "button1" and "button2".  (I could have just made
# everything locals, or simply ignored the overwrite, but it bugged me.  At
# the very least, window should be an instance variable, and having it be
# different from the other widgets was gratuitously ugly.  The difference
# between instance variables and local variables has nothing to do with the
# GTK anyway, and python itself already has a nice tutorial up on python.org.

# Another judgement call is that "pack_button" takes four arguments, but
# the last three have default values, and the C example is passing in what
# their default values are.  So I kept the code smaller, and more than made
# up for it with this big long comment. :)

class hello2:

  # Our new improved callback.  The data passed to this function
  # is printed to stdout.

  def callback(self, obj, data):
    print "Hello again - %s was pressed" % data

  # The "delete_event" signal is sent when they try to close the window.

  def delete_event(self, obj, event):
    gtk.mainquit()

  # The constructor function for the class

  def __init__(self):

    # We still don't have to call an equivalent of gtk_init manually.
    # Importing the gtk module did that for us as part of its setup.

    # Create a new window.

    self.window=gtk.Window()

    # This is a new call, which just sets the title of our
    # new window to "Hello Buttons!"

    self.window.set_title("Hello Buttons!")

    # Here we just set a handler for delete_event that immediately
    # exits GTK.

    self.window.connect("delete_event",self.delete_event)

    # Sets the border width of the window.

    self.window.set_border_width(10)

    # We create a box to pack widgets into.  This is described in detail
    # in the "packing" section.  The box is not really visible, it
    # is just used as a tool to arrange widgets.

    self.box1=gtk.HBox()

    # Put the box into the main window.

    self.window.add(self.box1)

    # Creates a button with the label "Button 1".

    self.button1=gtk.Button("Button 1")

    # Now when the button is clicked, we call the "callback" function
    # with a pointer to "Button 1" as its argument.

    self.button1.connect("clicked",self.callback,"button 1")

    # Instead of self.window.add(self.button1), we pack this button into the
    # invisible box, which has been packed into the window.

    self.box1.pack_start(self.button1)

    # Always remember this step, this tells GTK that our preparation for
    # this button is complete, and it can now be displayed.

    self.button1.show()

    # Do these same steps again to create a second button

    self.button2=gtk.Button("Button 2")

    # Call the same callback function with a different argument,
    # passing a pointer to "button 2" instead.

    self.button2.connect("clicked",self.callback,"button 2")
    self.box1.pack_start(self.button2)

    # The order in which we show the buttons is not really iportant, but I
    # Recommend showing the window last, so it all pops  up at once.

    self.button2.show()
    self.box1.show()
    self.window.show()

# If this module is being called directly rather than imported by another
# module...

if __name__ == "__main__":

  # Instantiate our dialog and loop dispatching events for it.

  hello2()
  gtk.mainloop()
#!/usr/bin/python

# example-start packbox packbox.py

import gtk, sys

# Python-specific notes:  The easy way to do "make_box" in python is just
# make a list and iterate through it, so I did that.  (It's much more
# "pythonic".)  At one point the C example gratuitously demonstrates the ? :
# operator, which Guido still won't put into Python.  Then again, python
# allows us to insert into arrays via a negatively indexed slice.  So there.

# I also redid the case statement in "main" to be list based.  It seems much
# happier now.


class packbox:

  # The "delete_event" signal is sent when they try to close the window.

  def delete_event(self, obj, event):
    gtk.mainquit()

  def make_box(self, homogeneous, spacing, expand, fill, padding):

    # Create a new hbox with the appropriate homogeneous
    # and spacing settings

    box=gtk.HBox(homogeneous, spacing)

    # Create a list of buttons with the appropriate settings, including
    # some with labels depending on the value of "expand" and "padding".

    temp=["gtk_box_pack","(box,","button,","%d);" % padding]
    if expand: temp.insert(3,"True,")
    else: temp.insert(3,"False,")
    if fill: temp[-1:-1]=["True,"]
    else: temp[-1:-1]=["False,"]

    # Add all the buttons from the list to the HBox, in order.

    for i in temp:
      button=gtk.Button(i)
      box.pack_start(button, expand, fill, padding)
      button.show()

    return box

  # The constructor function for the class

  def __init__(self, argv):

    # We still don't have to call an equivalent of gtk_init manually.
    # Importing the gtk module did that for us as part of its setup.

    if len(argv)!=2:
      sys.stderr.write("usage: packbox.py num, where num is 1, 2, or 3.\n")
      sys.exit(1)

    which=int(argv[1])

    # Create our window.

    self.window=gtk.Window()

    # You should always remember to connect the delete_event signal to the
    # main window.  This is very important for proper intuitive behavior.

    self.window.connect("delete_event",self.delete_event)
    self.window.set_border_width(10)

    # We create a vertical box (gtk.VBox) to pack horizontal boxes into.
    # This allows us to stack the horizontal boxes filled with buttons one
    # on top of the other in this vbox.

    box1=gtk.VBox()

    # Which example to show.  These correspond to the pictures above.
    # make_box args are: homogeneous, spacing, expand, fill, padding.

    # Should we demonstrate homogeneous?

    if which==1:
      for homogeneous in (False, True):
        list=(gtk.Label("gtk.HBox(%s, 0)" % homogeneous),
              self.make_box(homogeneous, 0, False, False, 0),
              self.make_box(homogeneous, 0, True, False, 0),
              self.make_box(homogeneous, 0, True, True, 0))

        # Align the label to the left side.  We'll discuss this function
        # and others in the section on Widget Attributes.

        list[0].set_alignment(0,0)

        # add the hboxes to the vbox

        for i in list:
          box1.pack_start(i)
          i.show()

        # Append a separator widget, filling its space with 5 pixels of padding.

        separator=gtk.HSeparator()
        box1.pack_start(separator, False, True, 5)

    # Should we demonstrate spacing?

    elif which==2:
      for spacepad in ((10, 0), (0, 10)):
        list=(gtk.Label("gtk.HBox(False, %s)" % spacepad[0]),
              self.make_box(False, spacepad[0], True, False, spacepad[1]),
              self.make_box(False, spacepad[0], True, True, spacepad[1]))

        # Align the label to the left side.  We'll discuss this function
        # and others in the section on Widget Attributes.

        list[0].set_alignment(0,0)

        # Add the hboxes to the vbox.

        for i in list:
          box1.pack_start(i)
          i.show()

        # Append a separator widget, filling its space with 5 pixels of padding.

        separator=gtk.HSeparator()
        box1.pack_start(separator, False, True, 5)

    # Should we demonstrate right justified widgets?

    elif which==3:

      # This demonstrates the ability to use HBox.pack_end() to
      # right justify widgets.

      box2 = self.make_box(False, 0, False, False, 0);
      label = gtk.Label("end")
      box2.pack_end(label)
      label.show()

      # Pack the hbox into the vbox.

      box1.pack_start(box2)
      box2.show()

      # Separator for the bottom.

      separator = gtk.HSeparator()

      # This explicitly sets the separator to 400 pixels wide by 5 pixels
      # high.  This is so the hbox we created will also be 400 pixels wide,
      # and the "end" label will be sparated from the other labels in the
      # hbox.  Otherwise, all the widgets in the hbox would be packed as
      # close together as possible.

      separator.set_size_request(400,5)

      # Append the separator to the vbox, with fill and padding.

      box1.pack_start(separator, False, True, 5)

    # Create another new hbox.. remember we can use as many as we need!

    quitbox = gtk.HBox()

    # Add our quit button, in its own HBox, quitting the app when clicked.

    button = gtk.Button("Quit")
    button.connect("clicked",gtk.mainquit)
    quitbox.pack_start(button, True)
    box1.pack_start(quitbox)

    # Pack the vbox (which now contains all our widgets) into the main window.

    self.window.add(box1)

    # Show everything left

    button.show()
    quitbox.show()
    box1.show()

    # Show the window last, so everything pops up at once.

    self.window.show()

# If this module is being called directly rather than imported by another
# module...

if __name__ == "__main__":

  # Instantiate our dialog and loop dispatching events for it.

  packbox(sys.argv)
  gtk.mainloop()

Reply via email to