Viewing file:      widget.py (4.49 KB)      -rwxr-xr-x Select action/file-type:    (+) |   (+) |   (+) | Code (+) | Session (+) |   (+) | SDB (+) |   (+) |   (+) |   (+) |   (+) |   (+) |
 
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:     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):     def __init__(self, text):         gtk.Widget.__init__(self)         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)
          # 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):         # 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 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()
          # 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)
  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)
      frame = gtk.Frame("Example frame")     win.add(frame)
      w = PyGtkWidget(TEXT)     frame.add(w)
      win.show_all()
      gtk.main()
  if __name__ == '__main__':     sys.exit(main(sys.argv)) 
  |