source: pkg/pygtk/branches/upstream/current/examples/gtk/widget.py @ 4

Revision 4, 4.5 KB checked in by alanbach-guest, 7 years ago (diff)

[svn-inject] Installing original source of pygtk

Line 
1import sys
2
3import gobject
4import pango
5import gtk
6from gtk import gdk
7
8if gtk.pygtk_version < (2, 8):
9    print "PyGtk 2.8 or later required for this example"
10    raise SystemExit
11
12try:
13    import cairo
14except ImportError:
15    raise SystemExit("cairo required for this example")
16
17TEXT = 'A GtkWidget implemented in PyGTK'
18BORDER_WIDTH = 10
19
20# A quite simple gtk.Widget subclass which demonstrates how to subclass
21# and do realizing, sizing and drawing.
22
23class PyGtkWidget(gtk.Widget):
24    def __init__(self, text):
25        gtk.Widget.__init__(self)
26        self._layout = self.create_pango_layout(text)
27        self._layout.set_font_description(pango.FontDescription("Sans Serif 16"))
28
29    # GtkWidget
30
31    def do_realize(self):
32        # The do_realize method is responsible for creating GDK (windowing system)
33        # resources. In this example we will create a new gdk.Window which we
34        # then draw on
35
36        # First set an internal flag telling that we're realized
37        self.set_flags(self.flags() | gtk.REALIZED)
38
39        # Create a new gdk.Window which we can draw on.
40        # Also say that we want to receive exposure events by setting
41        # the event_mask
42        self.window = gdk.Window(
43            self.get_parent_window(),
44            width=self.allocation.width,
45            height=self.allocation.height,
46            window_type=gdk.WINDOW_CHILD,
47            wclass=gdk.INPUT_OUTPUT,
48            event_mask=self.get_events() | gdk.EXPOSURE_MASK)
49
50        # Associate the gdk.Window with ourselves, Gtk+ needs a reference
51        # between the widget and the gdk window
52        self.window.set_user_data(self)
53
54        # Attach the style to the gdk.Window, a style contains colors and
55        # GC contextes used for drawing
56        self.style.attach(self.window)
57
58        # The default color of the background should be what
59        # the style (theme engine) tells us.
60        self.style.set_background(self.window, gtk.STATE_NORMAL)
61        self.window.move_resize(*self.allocation)
62
63    def do_unrealize(self):
64        # The do_unrealized method is responsible for freeing the GDK resources
65
66        # De-associate the window we created in do_realize with ourselves
67        self.window.set_user_data(None)
68
69    def do_size_request(self, requisition):
70        # The do_size_request method Gtk+ is calling on a widget to ask
71        # it the widget how large it wishes to be. It's not guaranteed
72        # that gtk+ will actually give this size to the widget
73
74        # In this case, we say that we want to be as big as the
75        # text is, plus a little border around it.
76        width, height = self._layout.get_size()
77        requisition.width = width // pango.SCALE + BORDER_WIDTH*4
78        requisition.height = height // pango.SCALE + BORDER_WIDTH*4
79
80    def do_size_allocate(self, allocation):
81        # The do_size_allocate is called by when the actual size is known
82        # and the widget is told how much space could actually be allocated
83
84        # Save the allocated space
85        self.allocation = allocation
86
87        # If we're realized, move and resize the window to the
88        # requested coordinates/positions
89        if self.flags() & gtk.REALIZED:
90            self.window.move_resize(*allocation)
91
92    def do_expose_event(self, event):
93        # The do_expose_event is called when the widget is asked to draw itself
94        # Remember that this will be called a lot of times, so it's usually
95        # a good idea to write this code as optimized as it can be, don't
96        # Create any resources in here.
97
98        # In this example, draw a rectangle in the foreground color
99        x, y, w, h = self.allocation
100        cr = self.window.cairo_create()
101        cr.set_source_color(self.style.fg[self.state])
102        cr.rectangle(BORDER_WIDTH, BORDER_WIDTH,
103                     w - 2*BORDER_WIDTH, h - 2*BORDER_WIDTH)
104        cr.set_line_width(5.0)
105        cr.set_line_join(cairo.LINE_JOIN_ROUND)
106        cr.stroke()
107
108        # And draw the text in the middle of the allocated space
109        fontw, fonth = self._layout.get_pixel_size()
110        cr.move_to((w - fontw)/2, (h - fonth)/2)
111        cr.update_layout(self._layout)
112        cr.show_layout(self._layout)
113
114gobject.type_register(PyGtkWidget)
115
116def main(args):
117    win = gtk.Window()
118    win.set_border_width(5)
119    win.set_title('Widget test')
120    win.connect('delete-event', gtk.main_quit)
121
122    frame = gtk.Frame("Example frame")
123    win.add(frame)
124
125    w = PyGtkWidget(TEXT)
126    frame.add(w)
127
128    win.show_all()
129
130    gtk.main()
131
132if __name__ == '__main__':
133    sys.exit(main(sys.argv))
Note: See TracBrowser for help on using the repository browser.