|
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 */ |