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()