File: chapter-signals.html

package info (click to toggle)
gtkmm-documentation 4.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 25,772 kB
  • sloc: cpp: 15,541; javascript: 1,208; makefile: 1,080; python: 401; xml: 106; perl: 67; sh: 8
file content (234 lines) | stat: -rw-r--r-- 8,236 bytes parent folder | download
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="highlight.min.css">
<script src="highlight.min.js"></script><script>
      hljs.configure({languages: ['cpp']});
      hljs.highlightAll();
    </script><title>Appendix B. Signals</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
<link rel="home" href="index.html" title="Programming with gtkmm 4">
<link rel="up" href="index.html" title="Programming with gtkmm 4">
<link rel="prev" href="sec-refptr-constness.html" title="Constness">
<link rel="next" href="sec-writing-signal-handlers.html" title="Writing signal handlers">
</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">Appendix B. Signals</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="sec-refptr-constness.html"><img src="icons/prev.png" alt="Prev"></a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="sec-writing-signal-handlers.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
</table>
<hr>
</div>
<div class="appendix">
<div class="titlepage"><div><div><h1 class="title">
<a name="chapter-signals"></a>Appendix B. Signals</h1></div></div></div>
<div class="toc">
<p><b>Table of Contents</b></p>
<ul class="toc">
<li><span class="section"><a href="chapter-signals.html#sec-connecting-signal-handlers">Connecting signal handlers</a></span></li>
<li><span class="section"><a href="sec-writing-signal-handlers.html">Writing signal handlers</a></span></li>
<li><span class="section"><a href="sec-disconnecting-signal-handlers.html">Disconnecting signal handlers</a></span></li>
<li><span class="section"><a href="sec-overriding-default-signal-handlers.html">Overriding default signal handlers</a></span></li>
<li><span class="section"><a href="sec-binding-extra-arguments.html">Binding extra arguments</a></span></li>
<li><span class="section"><a href="sec-eventsignals.html">Event signals</a></span></li>
<li><span class="section"><a href="sec-exceptions-in-signal-handlers.html">Exceptions in signal handlers</a></span></li>
</ul>
</div>


<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="sec-connecting-signal-handlers"></a>Connecting signal handlers</h2></div></div></div>


<p>
<span class="application">gtkmm</span> widget classes have signal accessor methods, such as
<code class="methodname">Gtk::Button::signal_clicked()</code>, which allow you to connect
your signal handler. Thanks to the flexibility of
<span class="application">libsigc++</span>, the callback library used by <span class="application">gtkmm</span>, the
signal handler can be almost any kind of function, but you will probably want
to use a class method. Among <span class="application">GTK</span> C coders, these
signal handlers are often named callbacks.
</p>

<p>
Here's an example of a signal handler being connected to a signal:
</p>

<pre class="programlisting"><code class="code">
#include &lt;gtkmm/button.h&gt;

void on_button_clicked()
{
  std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;
}

class some_class
{
public:
  some_class
  {
    button.signal_clicked().connect(sigc::ptr_fun(&amp;on_button_clicked));
  }
private:
  Gtk::Button button {"Hello World"};
};
</code></pre>

<p>
There's rather a lot to think about in this (non-functional) code.
First let's identify the parties involved:
</p>

<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">

<p>
The signal handler is <code class="methodname">on_button_clicked()</code>.
</p>
</li>
<li class="listitem">

<p>
We're hooking it up to the <code class="classname">Gtk::Button</code> object called
<code class="varname">button</code>.
</p>
</li>
<li class="listitem">

<p>
When the Button emits its <code class="literal">clicked</code> signal,
<code class="methodname">on_button_clicked()</code> will be called.
</p>
</li>
</ul></div>

<p>
Now let's look at the connection again:
</p>

<pre class="programlisting"><code class="code">    ...
    button.signal_clicked().connect(sigc::ptr_fun(&amp;on_button_clicked));
    ...
</code></pre>

<p>
Note that we don't pass a pointer to <code class="methodname">on_button_clicked()</code>
directly to the signal's <code class="methodname">connect()</code> method. Instead, we
call <code class="function">sigc::ptr_fun()</code>, and pass the result to
<code class="methodname">connect()</code>.
</p>

<p>
<code class="function">sigc::ptr_fun()</code>  generates a <code class="classname">sigc::slot</code>.
A slot is an object which
looks and feels like a function, but is actually an object. These are also
known as function objects, or functors.
<code class="function">sigc::ptr_fun()</code> generates a slot for a standalone function or static method.
<code class="function">sigc::mem_fun()</code> generates a slot for a member method of a particular instance.
</p>

<p>
A C++ lambda expression is a functor which can be implicitly converted to a
<code class="classname">sigc::slot</code> in the call to <code class="methodname">connect()</code>.
A lambda expression can be used instead of <code class="function">sigc::ptr_fun()</code>.
It's also possible to use a lambda expression instead of <code class="function">sigc::mem_fun()</code>,
but then you won't get automatic disconnection of the signal handler when a
<code class="classname">sigc::trackable</code>-derived object goes out of scope.
</p>

<p>
Here's a slightly larger example of slots in action:
</p>

<pre class="programlisting"><code class="code">
#include &lt;gtkmm/button.h&gt;

void on_button_clicked()
{
  std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;
}

class some_class
{
public:
  some_class
  {
    button.signal_clicked().connect(sigc::ptr_fun(&amp;on_button_clicked));
    button.signal_clicked().connect(sigc::mem_fun(*this, &amp;some_class::on_button_clicked));
  }
  void on_button_clicked();
private:
  Gtk::Button button {"Hello World"};
};
</code></pre>

<p>
The first call to <code class="methodname">connect()</code> is just like the one we saw
last time; nothing new here.</p>
<p>The next is more interesting.
<code class="function">sigc::mem_fun()</code> is called with two arguments. The first
argument is <em class="parameter"><code>*this</code></em>, which is the object that our
new slot will be pointing at. The second argument is a pointer to one of its
methods. This particular version of <code class="function">sigc::mem_fun()</code>
creates a slot which will, when "called", call the pointed-to method of the
specified object.
</p>

<p>
Another thing to note about this example is that we made the call to
<code class="methodname">connect()</code> twice for the same signal object. This is
perfectly fine - when the button is clicked, both signal handlers will be
called.
</p>

<p>
We just told you that the button's <code class="literal">clicked</code> signal is expecting
to call a method with no arguments. All signals have
requirements like this - you can't hook a function with two arguments
to a signal expecting none (unless you use an adapter, such as
<code class="function">sigc::bind()</code>, of course). Therefore, it's important to
know what type of signal handler you'll be expected to connect to a given
signal.
</p>
</div>












</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="sec-refptr-constness.html"><img src="icons/prev.png" alt="Prev"></a> </td>
<td width="20%" align="center"> </td>
<td width="40%" align="right"> <a accesskey="n" href="sec-writing-signal-handlers.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Constness </td>
<td width="20%" align="center"><a accesskey="h" href="index.html"><img src="icons/home.png" alt="Home"></a></td>
<td width="40%" align="right" valign="top"> Writing signal handlers</td>
</tr>
</table>
</div>
</body>
</html>