From 933c49dcb0953dd40d9cd1bc31448754f6eb82dd Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 23 Jan 2006 17:34:14 +0000 Subject: Add comments explaining what the overridden gtk+ methods does --- examples/gtk/widget.py | 149 +++++++++++++++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 62 deletions(-) (limited to 'examples') 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)) -- cgit v1.2.1