This file is indexed.

/usr/share/doc/python-gtk2-tutorial/html/sec-SteppingThroughHelloWorld.html is in python-gtk2-tutorial 2.4-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>2.4. Stepping Through Hello World</title><meta name="generator" content="DocBook XSL Stylesheets V1.65.1"><link rel="home" href="index.html" title="PyGTK 2.0 Tutorial"><link rel="up" href="ch-GettingStarted.html" title="Chapter 2. Getting Started"><link rel="previous" href="sec-Events.html" title="2.3. Events"><link rel="next" href="ch-MovingOn.html" title="Chapter 3. Moving On"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">2.4. Stepping Through Hello World</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="sec-Events.html">Prev</a> </td><th width="60%" align="center">Chapter 2. Getting Started</th><td width="20%" align="right"> <a accesskey="n" href="ch-MovingOn.html">Next</a></td></tr></table><hr></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="sec-SteppingThroughHelloWorld"></a>2.4. Stepping Through Hello World</h2></div></div><div></div></div><p>Now that we know the theory behind this, let's clarify by
walking through the example <a href="examples/helloworld.py" target="_top"><span><b class="command">helloworld.py</b></span></a>
program.</p><p>Lines 9-76 define the <tt class="classname">HelloWorld</tt> class
that contains all the callbacks as object methods and the object instance
initialization method. Let's examine the callback methods.</p><p>Lines 13-14 define the <tt class="methodname">hello</tt>() callback
method that will be called when the button is "clicked". When called the
method, prints "Hello World" to the console. We ignore the object instance,
the widget and the data parameters in this example, but most callbacks use
them. The <i class="parameter"><tt>data</tt></i> is defined with a default value of
<tt class="varname">None</tt> because PyGTK will not pass a data value if it is
not included in the <tt class="methodname">connect</tt>() call; this would
trigger an error since the callback is expecting three parameters and may
receive only two. Defining a default value of None allows the callback to be
called with two or three parameters without error. In this case the data
parameter could have been left out since the
<tt class="methodname">hello</tt>() method will always be called with just two
parameters (never called with user data). The next example will use the
<i class="parameter"><tt>data argument</tt></i> to tell us which button was
pressed.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  def hello(self, widget, data=None):
      print "Hello World"
</pre></td></tr></table><p>The next callback (lines 16-26) is a bit special. The
"delete_event" occurs when the window manager sends this event to the
application. We have a choice here as to what to do about these events. We
can ignore them, make some sort of response, or simply quit the
application.</p><p>The value you return in this callback lets GTK+ know what action
to take. By returning TRUE, we let it know that we don't want to have the
"destroy" signal emitted, keeping our application running. By returning
FALSE, we ask that "destroy" be emitted, which in turn will call our
"destroy" signal handler. Note the comments have been removed for
clarity.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  def delete_event(widget, event, data=None):
      print "delete event occurred"
      return False
</pre></td></tr></table><p>The <tt class="methodname">destroy</tt>() callback method (lines
28-30) causes the program to quit by calling
<tt class="function">gtk.main_quit</tt>() .  This function tells GTK+ that it is
to exit from <tt class="function">gtk.main</tt>() when control is returned to
it.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
  def destroy(widget, data=None):
      print "destroy signal occurred"
      gtk.main_quit()
</pre></td></tr></table><p>Lines 32-71 define the <tt class="classname">HelloWorld</tt> object
instance initialization method <tt class="methodname">__init__</tt>() that creates
the window and widgets used by the program.</p><p>Line 34 creates a new window, but it is not displayed until we
direct GTK+ to show the window near the end of our program. The window
reference is saved in an object instance attribute (self.window) for later
access.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
</pre></td></tr></table><p>Lines 41 and 46 illustrate two examples of connecting a signal
handler to an object, in this case, the <tt class="varname">window</tt>. Here, the
"delete_event" and "destroy" signals are caught. The first is emitted when
we use the window manager to kill the window, or when we use the
<tt class="classname">GtkWidget</tt> <tt class="methodname">destroy</tt>() method
call.  The second is emitted when, in the "delete_event" handler, we return
<tt class="varname">FALSE</tt>.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    self.window.connect("delete_event", self.delete_event)
    self.window.connect("destroy", self.destroy)
</pre></td></tr></table><p>Line 49 sets an attribute of a container object (in this case
the <tt class="varname">window</tt>) to have a blank area along the inside of it
10 pixels wide where no widgets will be placed. There are other similar
methods that we will look at in <a href="ch-SettingWidgetAttributes.html" title="Chapter 18. Setting Widget Attributes">Chapter 18, <i>Setting Widget Attributes</i></a></p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    self.window.set_border_width(10)
</pre></td></tr></table><p>Line 52 creates a new button and saves a reference to it in
<tt class="varname">self.button</tt>. The button will have the label "Hello World"
when displayed.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    self.button = gtk.Button("Hello World")
</pre></td></tr></table><p>In line 57 we attach a signal handler to the button so when it
emits the "clicked" signal, our <tt class="methodname">hello</tt>() callback
method is called. We are not passing any data to
<tt class="methodname">hello</tt>() so we just pass <tt class="varname">None</tt> as
the data. Obviously, the "clicked" signal is emitted when we click the
button with our mouse pointer. The user data parameter value
<tt class="varname">None</tt> is not required and could be removed. The callback
would then be called with one less parameter.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    self.button.connect("clicked", self.hello, None)
</pre></td></tr></table><p>We are also going to use this button to exit our program. Line
62 illustrates how the "destroy" signal may come from either the window
manager, or from our program. When the button is "clicked", same as above,
it calls the <tt class="methodname">hello</tt>() callback first, and then the
following one in the order they are set up. You may have as many callbacks
as you need, and all will be executed in the order you connected
them.</p><p>Since we want to use the <tt class="classname">GtkWidget</tt>
<tt class="methodname">destroy</tt>() method that accepts one argument (the
widget to be destroyed - in this case the <tt class="varname">window</tt>), we use
the <tt class="methodname">connect_object</tt>() method and pass it the
reference to the window. The <tt class="methodname">connect_object</tt>()
method arranges to pass the <i class="parameter"><tt>window</tt></i> as the first
callback argument instead of the button.</p><p>When the <tt class="classname">gtk.Widget</tt>
<tt class="methodname">destroy</tt>() method is called it will cause the
"destroy" signal to be emitted from the window which will in turn cause the
<tt class="classname">HelloWorld</tt> <tt class="methodname">destroy</tt>() method
to be called to end the program.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    self.button.connect_object("clicked", gtk.Widget.destroy, self.window)
</pre></td></tr></table><p>Line 65 is a packing call, which will be explained in depth
later on in <a href="ch-PackingWidgets.html" title="Chapter 4. Packing Widgets">Chapter 4, <i>Packing Widgets</i></a> . But it is fairly
easy to understand. It simply tells GTK+ that the button is to be placed in
the window where it will be displayed. Note that a GTK+ container can only
contain one widget. There are other widgets, described later, that are
designed to layout multiple widgets in various ways.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    self.window.add(self.button)
</pre></td></tr></table><p>Now we have everything set up the way we want it to be. With all
the signal handlers in place, and the button placed in the window where it
should be, we ask GTK+ (lines 66 and 69) to "show" the widgets on the screen.
The window widget is shown last so the whole window will pop up at once
rather than seeing the window pop up, and then the button forming inside of
it. Although with such a simple example, you'd never notice.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    self.button.show()

    self.window.show()
</pre></td></tr></table><p>Lines 73-75 define the <tt class="methodname">main</tt>() method
which calls the <tt class="function">gtk.main</tt>() function</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    def main(self):
        gtk.main()
</pre></td></tr></table><p>Lines 80-82 allow the program to run automatically if called
directly or as an argument of the python interpreter. Line 81 creates an
instance of the <tt class="classname">HelloWorld</tt> class and saves a
reference to it in the <tt class="varname">hello</tt> variable. Line 82 calls the
<tt class="classname">HelloWorld</tt> class <tt class="methodname">main</tt>()
method to start the GTK+ event processing loop.</p><table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="programlisting">
    if __name__ == "__main__":
        hello = HelloWorld()
        hello.main()
</pre></td></tr></table><p>Now, when we click the mouse button on a GTK+ button, the widget
emits a "clicked" signal. In order for us to use this information, our
program sets up a signal handler to catch that signal, which dispatches the
function of our choice. In our example, when the button we created is
"clicked", the <tt class="methodname">hello</tt>() method is called with the
<tt class="literal">None</tt> argument, and then the next handler for this signal
is called. The next handler calls the widget
<tt class="methodname">destroy</tt>() function with the window as its argument
thereby causing the window to emit the "destroy" signal, which is caught,
and calls our <tt class="classname">HelloWorld</tt>
<tt class="methodname">destroy</tt>() method</p><p>Another course of events is to use the window manager to kill
the window, which will cause the "delete_event" to be emitted. This will
call our "delete_event" handler. If we return <tt class="varname">TRUE</tt> here,
the window will be left as is and nothing will happen. Returning
<tt class="varname">FALSE</tt> will cause GTK+ to emit the "destroy" signal that
causes the <tt class="classname">HelloWorld</tt> "destroy" callback to be
called, exiting GTK.</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sec-Events.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch-GettingStarted.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch-MovingOn.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.3. Events </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 3. Moving On</td></tr></table></div></body></html>