0
|
1 |
/****************************************************************************
|
|
2 |
**
|
|
3 |
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
4 |
** All rights reserved.
|
|
5 |
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
6 |
**
|
|
7 |
** This file is part of the documentation of the Qt Toolkit.
|
|
8 |
**
|
|
9 |
** $QT_BEGIN_LICENSE:LGPL$
|
|
10 |
** No Commercial Usage
|
|
11 |
** This file contains pre-release code and may not be distributed.
|
|
12 |
** You may use this file in accordance with the terms and conditions
|
|
13 |
** contained in the Technology Preview License Agreement accompanying
|
|
14 |
** this package.
|
|
15 |
**
|
|
16 |
** GNU Lesser General Public License Usage
|
|
17 |
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
18 |
** General Public License version 2.1 as published by the Free Software
|
|
19 |
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
20 |
** packaging of this file. Please review the following information to
|
|
21 |
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
22 |
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
23 |
**
|
|
24 |
** In addition, as a special exception, Nokia gives you certain additional
|
|
25 |
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
26 |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
27 |
**
|
|
28 |
** If you have questions regarding the use of this file, please contact
|
|
29 |
** Nokia at qt-info@nokia.com.
|
|
30 |
**
|
|
31 |
**
|
|
32 |
**
|
|
33 |
**
|
|
34 |
**
|
|
35 |
**
|
|
36 |
**
|
|
37 |
**
|
|
38 |
** $QT_END_LICENSE$
|
|
39 |
**
|
|
40 |
****************************************************************************/
|
|
41 |
|
|
42 |
/*!
|
|
43 |
\page signalsandslots.html
|
|
44 |
\title Signals and Slots
|
|
45 |
\brief An overview of Qt's signals and slots inter-object
|
|
46 |
communication mechanism.
|
|
47 |
|
|
48 |
Signals and slots are used for communication between objects. The
|
|
49 |
signals and slots mechanism is a central feature of Qt and
|
|
50 |
probably the part that differs most from the features provided by
|
|
51 |
other frameworks.
|
|
52 |
|
|
53 |
\tableofcontents
|
|
54 |
|
|
55 |
\section1 Introduction
|
|
56 |
|
|
57 |
In GUI programming, when we change one widget, we often want
|
|
58 |
another widget to be notified. More generally, we want objects of
|
|
59 |
any kind to be able to communicate with one another. For example,
|
|
60 |
if a user clicks a \gui{Close} button, we probably want the
|
|
61 |
window's \l{QWidget::close()}{close()} function to be called.
|
|
62 |
|
|
63 |
Older toolkits achieve this kind of communication using
|
|
64 |
callbacks. A callback is a pointer to a function, so if you want
|
|
65 |
a processing function to notify you about some event you pass a
|
|
66 |
pointer to another function (the callback) to the processing
|
|
67 |
function. The processing function then calls the callback when
|
|
68 |
appropriate. Callbacks have two fundamental flaws: Firstly, they
|
|
69 |
are not type-safe. We can never be certain that the processing
|
|
70 |
function will call the callback with the correct arguments.
|
|
71 |
Secondly, the callback is strongly coupled to the processing
|
|
72 |
function since the processing function must know which callback
|
|
73 |
to call.
|
|
74 |
|
|
75 |
\section1 Signals and Slots
|
|
76 |
|
|
77 |
In Qt, we have an alternative to the callback technique: We use
|
|
78 |
signals and slots. A signal is emitted when a particular event
|
|
79 |
occurs. Qt's widgets have many predefined signals, but we can
|
|
80 |
always subclass widgets to add our own signals to them. A slot
|
|
81 |
is a function that is called in response to a particular signal.
|
|
82 |
Qt's widgets have many pre-defined slots, but it is common
|
|
83 |
practice to subclass widgets and add your own slots so that you
|
|
84 |
can handle the signals that you are interested in.
|
|
85 |
|
|
86 |
\img abstract-connections.png
|
|
87 |
\omit
|
|
88 |
\caption An abstract view of some signals and slots connections
|
|
89 |
\endomit
|
|
90 |
|
|
91 |
The signals and slots mechanism is type safe: The signature of a
|
|
92 |
signal must match the signature of the receiving slot. (In fact a
|
|
93 |
slot may have a shorter signature than the signal it receives
|
|
94 |
because it can ignore extra arguments.) Since the signatures are
|
|
95 |
compatible, the compiler can help us detect type mismatches.
|
|
96 |
Signals and slots are loosely coupled: A class which emits a
|
|
97 |
signal neither knows nor cares which slots receive the signal.
|
|
98 |
Qt's signals and slots mechanism ensures that if you connect a
|
|
99 |
signal to a slot, the slot will be called with the signal's
|
|
100 |
parameters at the right time. Signals and slots can take any
|
|
101 |
number of arguments of any type. They are completely type safe.
|
|
102 |
|
|
103 |
All classes that inherit from QObject or one of its subclasses
|
|
104 |
(e.g., QWidget) can contain signals and slots. Signals are emitted by
|
|
105 |
objects when they change their state in a way that may be interesting
|
|
106 |
to other objects. This is all the object does to communicate. It
|
|
107 |
does not know or care whether anything is receiving the signals it
|
|
108 |
emits. This is true information encapsulation, and ensures that the
|
|
109 |
object can be used as a software component.
|
|
110 |
|
|
111 |
Slots can be used for receiving signals, but they are also normal
|
|
112 |
member functions. Just as an object does not know if anything receives
|
|
113 |
its signals, a slot does not know if it has any signals connected to
|
|
114 |
it. This ensures that truly independent components can be created with
|
|
115 |
Qt.
|
|
116 |
|
|
117 |
You can connect as many signals as you want to a single slot, and a
|
|
118 |
signal can be connected to as many slots as you need. It is even
|
|
119 |
possible to connect a signal directly to another signal. (This will
|
|
120 |
emit the second signal immediately whenever the first is emitted.)
|
|
121 |
|
|
122 |
Together, signals and slots make up a powerful component programming
|
|
123 |
mechanism.
|
|
124 |
|
|
125 |
\section1 A Small Example
|
|
126 |
|
|
127 |
A minimal C++ class declaration might read:
|
|
128 |
|
|
129 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.h 0
|
|
130 |
|
|
131 |
A small QObject-based class might read:
|
|
132 |
|
|
133 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.h 1
|
|
134 |
\codeline
|
|
135 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.h 2
|
|
136 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.h 3
|
|
137 |
|
|
138 |
The QObject-based version has the same internal state, and provides
|
|
139 |
public methods to access the state, but in addition it has support
|
|
140 |
for component programming using signals and slots. This class can
|
|
141 |
tell the outside world that its state has changed by emitting a
|
|
142 |
signal, \c{valueChanged()}, and it has a slot which other objects
|
|
143 |
can send signals to.
|
|
144 |
|
|
145 |
All classes that contain signals or slots must mention
|
|
146 |
Q_OBJECT at the top of their declaration. They must also derive
|
|
147 |
(directly or indirectly) from QObject.
|
|
148 |
|
|
149 |
Slots are implemented by the application programmer.
|
|
150 |
Here is a possible implementation of the \c{Counter::setValue()}
|
|
151 |
slot:
|
|
152 |
|
|
153 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 0
|
|
154 |
|
|
155 |
The \c{emit} line emits the signal \c valueChanged() from the
|
|
156 |
object, with the new value as argument.
|
|
157 |
|
|
158 |
In the following code snippet, we create two \c Counter objects
|
|
159 |
and connect the first object's \c valueChanged() signal to the
|
|
160 |
second object's \c setValue() slot using QObject::connect():
|
|
161 |
|
|
162 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 1
|
|
163 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 2
|
|
164 |
\codeline
|
|
165 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 3
|
|
166 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 4
|
|
167 |
|
|
168 |
Calling \c{a.setValue(12)} makes \c{a} emit a
|
|
169 |
\c{valueChanged(12)} signal, which \c{b} will receive in its
|
|
170 |
\c{setValue()} slot, i.e. \c{b.setValue(12)} is called. Then
|
|
171 |
\c{b} emits the same \c{valueChanged()} signal, but since no slot
|
|
172 |
has been connected to \c{b}'s \c{valueChanged()} signal, the
|
|
173 |
signal is ignored.
|
|
174 |
|
|
175 |
Note that the \c{setValue()} function sets the value and emits
|
|
176 |
the signal only if \c{value != m_value}. This prevents infinite
|
|
177 |
looping in the case of cyclic connections (e.g., if
|
|
178 |
\c{b.valueChanged()} were connected to \c{a.setValue()}).
|
|
179 |
|
|
180 |
By default, for every connection you make, a signal is emitted;
|
|
181 |
two signals are emitted for duplicate connections. You can break
|
|
182 |
all of these connections with a single disconnect() call.
|
|
183 |
If you pass the Qt::UniqueConnection \a type, the connection will only
|
|
184 |
be made if it is not a duplicate. If there is already a duplicate
|
|
185 |
(exact same signal to the exact same slot on the same objects),
|
|
186 |
the connection will fail and connect will return false
|
|
187 |
|
|
188 |
This example illustrates that objects can work together without needing to
|
|
189 |
know any information about each other. To enable this, the objects only
|
|
190 |
need to be connected together, and this can be achieved with some simple
|
|
191 |
QObject::connect() function calls, or with \c{uic}'s
|
|
192 |
\l{Using a Designer UI File in Your Application#Automatic Connections}
|
|
193 |
{automatic connections} feature.
|
|
194 |
|
|
195 |
\section1 Building the Example
|
|
196 |
|
|
197 |
The C++ preprocessor changes or removes the \c{signals},
|
|
198 |
\c{slots}, and \c{emit} keywords so that the compiler is
|
|
199 |
presented with standard C++.
|
|
200 |
|
|
201 |
By running the \l moc on class definitions that contain signals
|
|
202 |
or slots, a C++ source file is produced which should be compiled
|
|
203 |
and linked with the other object files for the application. If
|
|
204 |
you use \l qmake, the makefile rules to automatically invoke \c
|
|
205 |
moc will be added to your project's makefile.
|
|
206 |
|
|
207 |
\section1 Signals
|
|
208 |
|
|
209 |
Signals are emitted by an object when its internal state has changed
|
|
210 |
in some way that might be interesting to the object's client or owner.
|
|
211 |
Only the class that defines a signal and its subclasses can emit the
|
|
212 |
signal.
|
|
213 |
|
|
214 |
When a signal is emitted, the slots connected to it are usually
|
|
215 |
executed immediately, just like a normal function call. When this
|
|
216 |
happens, the signals and slots mechanism is totally independent of
|
|
217 |
any GUI event loop. Execution of the code following the \c emit
|
|
218 |
statement will occur once all slots have returned. The situation is
|
|
219 |
slightly different when using \l{Qt::ConnectionType}{queued
|
|
220 |
connections}; in such a case, the code following the \c emit keyword
|
|
221 |
will continue immediately, and the slots will be executed later.
|
|
222 |
|
|
223 |
If several slots are connected to one signal, the slots will be
|
|
224 |
executed one after the other, in the order they have been connected,
|
|
225 |
when the signal is emitted.
|
|
226 |
|
|
227 |
Signals are automatically generated by the \l moc and must not be
|
|
228 |
implemented in the \c .cpp file. They can never have return types
|
|
229 |
(i.e. use \c void).
|
|
230 |
|
|
231 |
A note about arguments: Our experience shows that signals and slots
|
|
232 |
are more reusable if they do not use special types. If
|
|
233 |
QScrollBar::valueChanged() were to use a special type such as the
|
|
234 |
hypothetical QScrollBar::Range, it could only be connected to
|
|
235 |
slots designed specifically for QScrollBar. Connecting different
|
|
236 |
input widgets together would be impossible.
|
|
237 |
|
|
238 |
\section1 Slots
|
|
239 |
|
|
240 |
A slot is called when a signal connected to it is emitted. Slots are
|
|
241 |
normal C++ functions and can be called normally; their only special
|
|
242 |
feature is that signals can be connected to them.
|
|
243 |
|
|
244 |
Since slots are normal member functions, they follow the normal C++
|
|
245 |
rules when called directly. However, as slots, they can be invoked
|
|
246 |
by any component, regardless of its access level, via a signal-slot
|
|
247 |
connection. This means that a signal emitted from an instance of an
|
|
248 |
arbitrary class can cause a private slot to be invoked in an instance
|
|
249 |
of an unrelated class.
|
|
250 |
|
|
251 |
You can also define slots to be virtual, which we have found quite
|
|
252 |
useful in practice.
|
|
253 |
|
|
254 |
Compared to callbacks, signals and slots are slightly slower
|
|
255 |
because of the increased flexibility they provide, although the
|
|
256 |
difference for real applications is insignificant. In general,
|
|
257 |
emitting a signal that is connected to some slots, is
|
|
258 |
approximately ten times slower than calling the receivers
|
|
259 |
directly, with non-virtual function calls. This is the overhead
|
|
260 |
required to locate the connection object, to safely iterate over
|
|
261 |
all connections (i.e. checking that subsequent receivers have not
|
|
262 |
been destroyed during the emission), and to marshall any
|
|
263 |
parameters in a generic fashion. While ten non-virtual function
|
|
264 |
calls may sound like a lot, it's much less overhead than any \c
|
|
265 |
new or \c delete operation, for example. As soon as you perform a
|
|
266 |
string, vector or list operation that behind the scene requires
|
|
267 |
\c new or \c delete, the signals and slots overhead is only
|
|
268 |
responsible for a very small proportion of the complete function
|
|
269 |
call costs.
|
|
270 |
|
|
271 |
The same is true whenever you do a system call in a slot; or
|
|
272 |
indirectly call more than ten functions. On an i586-500, you can
|
|
273 |
emit around 2,000,000 signals per second connected to one
|
|
274 |
receiver, or around 1,200,000 per second connected to two
|
|
275 |
receivers. The simplicity and flexibility of the signals and
|
|
276 |
slots mechanism is well worth the overhead, which your users
|
|
277 |
won't even notice.
|
|
278 |
|
|
279 |
Note that other libraries that define variables called \c signals
|
|
280 |
or \c slots may cause compiler warnings and errors when compiled
|
|
281 |
alongside a Qt-based application. To solve this problem, \c
|
|
282 |
#undef the offending preprocessor symbol.
|
|
283 |
|
|
284 |
\section1 Meta-Object Information
|
|
285 |
|
|
286 |
The meta-object compiler (\l moc) parses the class declaration in
|
|
287 |
a C++ file and generates C++ code that initializes the
|
|
288 |
meta-object. The meta-object contains the names of all the signal
|
|
289 |
and slot members, as well as pointers to these functions.
|
|
290 |
|
|
291 |
The meta-object contains additional information such as the
|
|
292 |
object's \link QObject::className() class name\endlink. You can
|
|
293 |
also check if an object \link QObject::inherits()
|
|
294 |
inherits\endlink a specific class, for example:
|
|
295 |
|
|
296 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 5
|
|
297 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 6
|
|
298 |
|
|
299 |
The meta-object information is also used by qobject_cast<T>(), which
|
|
300 |
is similar to QObject::inherits() but is less error-prone:
|
|
301 |
|
|
302 |
\snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 7
|
|
303 |
|
|
304 |
See \l{Meta-Object System} for more information.
|
|
305 |
|
|
306 |
\section1 A Real Example
|
|
307 |
|
|
308 |
Here is a simple commented example of a widget.
|
|
309 |
|
|
310 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 0
|
|
311 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 1
|
|
312 |
\codeline
|
|
313 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 2
|
|
314 |
\codeline
|
|
315 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 3
|
|
316 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 4
|
|
317 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 5
|
|
318 |
|
|
319 |
\c LcdNumber inherits QObject, which has most of the signal-slot
|
|
320 |
knowledge, via QFrame and QWidget. It is somewhat similar to the
|
|
321 |
built-in QLCDNumber widget.
|
|
322 |
|
|
323 |
The Q_OBJECT macro is expanded by the preprocessor to declare
|
|
324 |
several member functions that are implemented by the \c{moc}; if
|
|
325 |
you get compiler errors along the lines of "undefined reference
|
|
326 |
to vtable for \c{LcdNumber}", you have probably forgotten to
|
|
327 |
\l{moc}{run the moc} or to include the moc output in the link
|
|
328 |
command.
|
|
329 |
|
|
330 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 6
|
|
331 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 7
|
|
332 |
|
|
333 |
It's not obviously relevant to the moc, but if you inherit
|
|
334 |
QWidget you almost certainly want to have the \c parent argument
|
|
335 |
in your constructor and pass it to the base class's constructor.
|
|
336 |
|
|
337 |
Some destructors and member functions are omitted here; the \c
|
|
338 |
moc ignores member functions.
|
|
339 |
|
|
340 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 8
|
|
341 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 9
|
|
342 |
|
|
343 |
\c LcdNumber emits a signal when it is asked to show an impossible
|
|
344 |
value.
|
|
345 |
|
|
346 |
If you don't care about overflow, or you know that overflow
|
|
347 |
cannot occur, you can ignore the \c overflow() signal, i.e. don't
|
|
348 |
connect it to any slot.
|
|
349 |
|
|
350 |
If on the other hand you want to call two different error
|
|
351 |
functions when the number overflows, simply connect the signal to
|
|
352 |
two different slots. Qt will call both (in arbitrary order).
|
|
353 |
|
|
354 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 10
|
|
355 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 11
|
|
356 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 12
|
|
357 |
\codeline
|
|
358 |
\snippet doc/src/snippets/signalsandslots/lcdnumber.h 13
|
|
359 |
|
|
360 |
A slot is a receiving function used to get information about
|
|
361 |
state changes in other widgets. \c LcdNumber uses it, as the code
|
|
362 |
above indicates, to set the displayed number. Since \c{display()}
|
|
363 |
is part of the class's interface with the rest of the program,
|
|
364 |
the slot is public.
|
|
365 |
|
|
366 |
Several of the example programs connect the
|
|
367 |
\l{QScrollBar::valueChanged()}{valueChanged()} signal of a
|
|
368 |
QScrollBar to the \c display() slot, so the LCD number
|
|
369 |
continuously shows the value of the scroll bar.
|
|
370 |
|
|
371 |
Note that \c display() is overloaded; Qt will select the
|
|
372 |
appropriate version when you connect a signal to the slot. With
|
|
373 |
callbacks, you'd have to find five different names and keep track
|
|
374 |
of the types yourself.
|
|
375 |
|
|
376 |
Some irrelevant member functions have been omitted from this
|
|
377 |
example.
|
|
378 |
|
|
379 |
\section1 Advanced Signals and Slots Usage
|
|
380 |
|
|
381 |
For cases where you may require information on the sender of the
|
|
382 |
signal, Qt provides the QObject::sender() function, which returns
|
|
383 |
a pointer to the object that sent the signal.
|
|
384 |
|
|
385 |
The QSignalMapper class is provided for situations where many
|
|
386 |
signals are connected to the same slot and the slot needs to
|
|
387 |
handle each signal differently.
|
|
388 |
|
|
389 |
Suppose you have three push buttons that determine which file you
|
|
390 |
will open: "Tax File", "Accounts File", or "Report File".
|
|
391 |
|
|
392 |
In order to open the correct file, you use QSignalMapper::setMapping() to
|
|
393 |
map all the clicked() signals to a QSignalMapper object. Then you connect
|
|
394 |
the file's QPushButton::clicked() signal to the QSignalMapper::map() slot.
|
|
395 |
|
|
396 |
\snippet doc/src/snippets/signalmapper/filereader.cpp 0
|
|
397 |
|
|
398 |
Then, you connect the \l{QSignalMapper::}{mapped()} signal to
|
|
399 |
\c{readFile()} where a different file will be opened, depending on
|
|
400 |
which push button is pressed.
|
|
401 |
|
|
402 |
\snippet doc/src/snippets/signalmapper/filereader.cpp 1
|
|
403 |
|
|
404 |
\sa {Meta-Object System}, {Qt's Property System}
|
|
405 |
|
|
406 |
\target 3rd Party Signals and Slots
|
|
407 |
\section2 Using Qt with 3rd Party Signals and Slots
|
|
408 |
|
|
409 |
It is possible to use Qt with a 3rd party signal/slot mechanism.
|
|
410 |
You can even use both mechanisms in the same project. Just add the
|
|
411 |
following line to your qmake project (.pro) file.
|
|
412 |
|
|
413 |
\snippet doc/src/snippets/code/doc_src_containers.qdoc 22
|
|
414 |
|
|
415 |
It tells Qt not to define the moc keywords \c{signals}, \c{slots},
|
|
416 |
and \c{emit}, because these names will be used by a 3rd party
|
|
417 |
library, e.g. Boost. Then to continue using Qt signals and slots
|
|
418 |
with the \c{no_keywords} flag, simply replace all uses of the Qt
|
|
419 |
moc keywords in your sources with the corresponding Qt macros
|
|
420 |
Q_SIGNALS (or Q_SIGNAL), Q_SLOTS (or Q_SLOT), and Q_EMIT.
|
|
421 |
*/
|