summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Dahlin <johan@src.gnome.org>2006-01-23 17:34:14 +0000
committerJohan Dahlin <johan@src.gnome.org>2006-01-23 17:34:14 +0000
commit933c49dcb0953dd40d9cd1bc31448754f6eb82dd (patch)
treed227bde2295fbaebf36d573ccce568d852b4686d
parent07daf2c32106024f1ef71684cdd7fb11ad0d8686 (diff)
downloadpygtk-933c49dcb0953dd40d9cd1bc31448754f6eb82dd.tar.gz
Add comments explaining what the overridden gtk+ methods does
-rw-r--r--examples/gtk/widget.py149
1 files changed, 87 insertions, 62 deletions
diff --git a/examples/gtk/widget.py b/examples/gtk/widget.py
index 6cbfb72c..fbda21eb 100644
--- a/examples/gtk/widget.py
+++ b/examples/gtk/widget.py
@@ -1,108 +1,133 @@
-import pygtk
-pygtk.require('2.0')
+import sys
import gobject
import pango
import gtk
from gtk import gdk
+
+if gtk.pygtk_version < (2, 8):
+ print "PyGtk 2.8 or later required for this example"
+ raise SystemExit
+
try:
import cairo
except ImportError:
- pass
-
-if gtk.pygtk_version < (2,3,93):
- print "PyGtk 2.3.93 or later required for this example"
- raise SystemExit
+ raise SystemExit("cairo required for this example")
TEXT = 'A GtkWidget implemented in PyGTK'
BORDER_WIDTH = 10
+# A quite simple gtk.Widget subclass which demonstrates how to subclass
+# and do realizing, sizing and drawing.
+
class PyGtkWidget(gtk.Widget):
- __gsignals__ = { 'realize': 'override',
- 'expose-event' : 'override',
- 'size-allocate': 'override',
- 'size-request': 'override',
- }
- def __init__(self):
+ def __init__(self, text):
gtk.Widget.__init__(self)
- self.draw_gc = None
- self.layout = self.create_pango_layout(TEXT)
- self.layout.set_font_description(pango.FontDescription("sans serif 16"))
-
+ self._layout = self.create_pango_layout(text)
+ self._layout.set_font_description(pango.FontDescription("Sans Serif 16"))
+
+ # GtkWidget
+
def do_realize(self):
+ # The do_realize method is responsible for creating GDK (windowing system)
+ # resources. In this example we will create a new gdk.Window which we
+ # then draw on
+
+ # First set an internal flag telling that we're realized
self.set_flags(self.flags() | gtk.REALIZED)
- self.window = gdk.Window(self.get_parent_window(),
- width=self.allocation.width,
- height=self.allocation.height,
- window_type=gdk.WINDOW_CHILD,
- wclass=gdk.INPUT_OUTPUT,
- event_mask=self.get_events() | gdk.EXPOSURE_MASK)
- if not hasattr(self.window, "cairo_create"):
- self.draw_gc = gdk.GC(self.window,
- line_width=5,
- line_style=gdk.SOLID,
- join_style=gdk.JOIN_ROUND)
+
+ # Create a new gdk.Window which we can draw on.
+ # Also say that we want to receive exposure events by setting
+ # the event_mask
+ self.window = gdk.Window(
+ self.get_parent_window(),
+ width=self.allocation.width,
+ height=self.allocation.height,
+ window_type=gdk.WINDOW_CHILD,
+ wclass=gdk.INPUT_OUTPUT,
+ event_mask=self.get_events() | gdk.EXPOSURE_MASK)
+
+ # Associate the gdk.Window with ourselves, Gtk+ needs a reference
+ # between the widget and the gdk window
self.window.set_user_data(self)
+
+ # Attach the style to the gdk.Window, a style contains colors and
+ # GC contextes used for drawing
self.style.attach(self.window)
+
+ # The default color of the background should be what
+ # the style (theme engine) tells us.
self.style.set_background(self.window, gtk.STATE_NORMAL)
self.window.move_resize(*self.allocation)
def do_unrealize(self):
+ # The do_unrealized method is responsible for freeing the GDK resources
+
+ # De-associate the window we created in do_realize with ourselves
self.window.set_user_data(None)
-
+
def do_size_request(self, requisition):
- width, height = self.layout.get_size()
+ # The do_size_request method Gtk+ is calling on a widget to ask
+ # it the widget how large it wishes to be. It's not guaranteed
+ # that gtk+ will actually give this size to the widget
+
+ # In this case, we say that we want to be as big as the
+ # text is, plus a little border around it.
+ width, height = self._layout.get_size()
requisition.width = width // pango.SCALE + BORDER_WIDTH*4
requisition.height = height // pango.SCALE + BORDER_WIDTH*4
def do_size_allocate(self, allocation):
+ # The do_size_allocate is called by when the actual size is known
+ # and the widget is told how much space could actually be allocated
+
+ # Save the allocated space
self.allocation = allocation
+
+ # If we're realized, move and resize the window to the
+ # requested coordinates/positions
if self.flags() & gtk.REALIZED:
self.window.move_resize(*allocation)
- def _expose_gdk(self, event):
- x, y, w, h = self.allocation
- self.window.draw_rectangle(self.draw_gc, False,
- BORDER_WIDTH, BORDER_WIDTH,
- w - BORDER_WIDTH * 2, h - BORDER_WIDTH * 2)
- fontw, fonth = self.layout.get_pixel_size()
- self.style.paint_layout(self.window, self.state, False,
- event.area, self, "label",
- (w - fontw) / 2, (h - fonth) / 2,
- self.layout)
-
- def _expose_cairo(self, event, cr):
+ def do_expose_event(self, event):
+ # The do_expose_event is called when the widget is asked to draw itself
+ # Remember that this will be called a lot of times, so it's usually
+ # a good idea to write this code as optimized as it can be, don't
+ # Create any resources in here.
+
+ # In this example, draw a rectangle in the foreground color
x, y, w, h = self.allocation
+ cr = self.window.cairo_create()
cr.set_source_color(self.style.fg[self.state])
cr.rectangle(BORDER_WIDTH, BORDER_WIDTH,
w - 2*BORDER_WIDTH, h - 2*BORDER_WIDTH)
cr.set_line_width(5.0)
cr.set_line_join(cairo.LINE_JOIN_ROUND)
cr.stroke()
- fontw, fonth = self.layout.get_pixel_size()
+
+ # And draw the text in the middle of the allocated space
+ fontw, fonth = self._layout.get_pixel_size()
cr.move_to((w - fontw)/2, (h - fonth)/2)
- cr.update_layout(self.layout)
- cr.show_layout(self.layout)
+ cr.update_layout(self._layout)
+ cr.show_layout(self._layout)
- def do_expose_event(self, event):
- self.chain(event)
- try:
- cr = self.window.cairo_create()
- except AttributeError:
- return self._expose_gdk(event)
- return self._expose_cairo(event, cr)
-
+gobject.type_register(PyGtkWidget)
+
+def main(args):
+ win = gtk.Window()
+ win.set_border_width(5)
+ win.set_title('Widget test')
+ win.connect('delete-event', gtk.main_quit)
-win = gtk.Window()
-win.set_title(TEXT)
-win.connect('delete-event', gtk.main_quit)
+ frame = gtk.Frame("Example frame")
+ win.add(frame)
-frame = gtk.Frame("Example frame")
-win.add(frame)
+ w = PyGtkWidget(TEXT)
+ frame.add(w)
-w = PyGtkWidget()
-frame.add(w)
+ win.show_all()
-win.show_all()
+ gtk.main()
-gtk.main()
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))