| [190] | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|---|
| 2 | <!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/signalsandslots.doc:36 -->
|
|---|
| 3 | <html>
|
|---|
| 4 | <head>
|
|---|
| 5 | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|---|
| 6 | <title>Signals and Slots</title>
|
|---|
| 7 | <style type="text/css"><!--
|
|---|
| 8 | fn { margin-left: 1cm; text-indent: -1cm; }
|
|---|
| 9 | a:link { color: #004faf; text-decoration: none }
|
|---|
| 10 | a:visited { color: #672967; text-decoration: none }
|
|---|
| 11 | body { background: #ffffff; color: black; }
|
|---|
| 12 | --></style>
|
|---|
| 13 | </head>
|
|---|
| 14 | <body>
|
|---|
| 15 |
|
|---|
| 16 | <table border="0" cellpadding="0" cellspacing="0" width="100%">
|
|---|
| 17 | <tr bgcolor="#E5E5E5">
|
|---|
| 18 | <td valign=center>
|
|---|
| 19 | <a href="index.html">
|
|---|
| 20 | <font color="#004faf">Home</font></a>
|
|---|
| 21 | | <a href="classes.html">
|
|---|
| 22 | <font color="#004faf">All Classes</font></a>
|
|---|
| 23 | | <a href="mainclasses.html">
|
|---|
| 24 | <font color="#004faf">Main Classes</font></a>
|
|---|
| 25 | | <a href="annotated.html">
|
|---|
| 26 | <font color="#004faf">Annotated</font></a>
|
|---|
| 27 | | <a href="groups.html">
|
|---|
| 28 | <font color="#004faf">Grouped Classes</font></a>
|
|---|
| 29 | | <a href="functions.html">
|
|---|
| 30 | <font color="#004faf">Functions</font></a>
|
|---|
| 31 | </td>
|
|---|
| 32 | <td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>Signals and Slots</h1>
|
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 | <p> Signals and slots are used for communication between objects. The
|
|---|
| 36 | signal/slot mechanism is a central feature of Qt and probably the
|
|---|
| 37 | part that differs most from other toolkits.
|
|---|
| 38 | <p> In GUI programming we often want a change in one widget to be notified
|
|---|
| 39 | to another widget. More generally, we want objects of any kind to be
|
|---|
| 40 | able to communicate with one another. For example if we were parsing
|
|---|
| 41 | an XML file we might want to notify a list view that we're using to
|
|---|
| 42 | represent the XML file's structure whenever we encounter a new tag.
|
|---|
| 43 | <p> Older toolkits achieve this kind of communication using callbacks. A
|
|---|
| 44 | callback is a pointer to a function, so if you want a processing
|
|---|
| 45 | function to notify you about some event you pass a pointer to another
|
|---|
| 46 | function (the callback) to the processing function. The processing
|
|---|
| 47 | function then calls the callback when appropriate. Callbacks have two
|
|---|
| 48 | fundamental flaws. Firstly they are not type safe. We can never be
|
|---|
| 49 | certain that the processing function will call the callback with the
|
|---|
| 50 | correct arguments. Secondly the callback is strongly coupled to the
|
|---|
| 51 | processing function since the processing function must know which
|
|---|
| 52 | callback to call.
|
|---|
| 53 | <p> <center><img src="abstract-connections.png"></center> <blockquote><p align="center"><em> An abstract view of some signals and slots connections
|
|---|
| 54 | </em></p>
|
|---|
| 55 | </blockquote><p> In Qt we have an alternative to the callback technique. We use signals
|
|---|
| 56 | and slots. A signal is emitted when a particular event occurs. Qt's
|
|---|
| 57 | widgets have many pre-defined signals, but we can always subclass to
|
|---|
| 58 | add our own. A slot is a function that is called in reponse to a
|
|---|
| 59 | particular signal. Qt's widgets have many pre-defined slots, but it is
|
|---|
| 60 | common practice to add your own slots so that you can handle the
|
|---|
| 61 | signals that you are interested in.
|
|---|
| 62 | <p> The signals and slots mechanism is type safe: the signature of a
|
|---|
| 63 | signal must match the signature of the receiving slot. (In fact a slot
|
|---|
| 64 | may have a shorter signature than the signal it receives because it
|
|---|
| 65 | can ignore extra arguments.) Since the signatures are compatible, the
|
|---|
| 66 | compiler can help us detect type mismatches. Signals and slots are
|
|---|
| 67 | loosely coupled: a class which emits a signal neither knows nor cares
|
|---|
| 68 | which slots receive the signal. Qt's signals and slots mechanism
|
|---|
| 69 | ensures that if you connect a signal to a slot, the slot will be
|
|---|
| 70 | called with the signal's parameters at the right time. Signals and
|
|---|
| 71 | slots can take any number of arguments of any type. They are
|
|---|
| 72 | completely typesafe: no more callback core dumps!
|
|---|
| 73 | <p> All classes that inherit from <a href="qobject.html">QObject</a> or one of its subclasses
|
|---|
| 74 | (e.g. <a href="qwidget.html">QWidget</a>) can contain signals and slots. Signals are emitted by
|
|---|
| 75 | objects when they change their state in a way that may be interesting
|
|---|
| 76 | to the outside world. This is all the object does to communicate. It
|
|---|
| 77 | does not know or care whether anything is receiving the signals it
|
|---|
| 78 | emits. This is true information encapsulation, and ensures that the
|
|---|
| 79 | object can be used as a software component.
|
|---|
| 80 | <p> <center><img src="concrete-connections.png"></center> <blockquote><p align="center"><em> An example of signals and slots connections
|
|---|
| 81 | </em></p>
|
|---|
| 82 | </blockquote><p> Slots can be used for receiving signals, but they are also normal
|
|---|
| 83 | member functions. Just as an object does not know if anything receives
|
|---|
| 84 | its signals, a slot does not know if it has any signals connected to
|
|---|
| 85 | it. This ensures that truly independent components can be created with
|
|---|
| 86 | Qt.
|
|---|
| 87 | <p> You can connect as many signals as you want to a single slot, and a
|
|---|
| 88 | signal can be connected to as many slots as you desire. It is even
|
|---|
| 89 | possible to connect a signal directly to another signal. (This will
|
|---|
| 90 | emit the second signal immediately whenever the first is emitted.)
|
|---|
| 91 | <p> Together, signals and slots make up a powerful component programming
|
|---|
| 92 | mechanism.
|
|---|
| 93 | <p> <h2> A Small Example
|
|---|
| 94 | </h2>
|
|---|
| 95 | <a name="1"></a><p> A minimal C++ class declaration might read:
|
|---|
| 96 | <p> <pre>
|
|---|
| 97 | class Foo
|
|---|
| 98 | {
|
|---|
| 99 | public:
|
|---|
| 100 | Foo();
|
|---|
| 101 | int value() const { return val; }
|
|---|
| 102 | void setValue( int );
|
|---|
| 103 | private:
|
|---|
| 104 | int val;
|
|---|
| 105 | };
|
|---|
| 106 | </pre>
|
|---|
| 107 |
|
|---|
| 108 | <p> A small Qt class might read:
|
|---|
| 109 | <p> <pre>
|
|---|
| 110 | class Foo : public <a href="qobject.html">QObject</a>
|
|---|
| 111 | {
|
|---|
| 112 | <a href="metaobjects.html#Q_OBJECT">Q_OBJECT</a>
|
|---|
| 113 | public:
|
|---|
| 114 | Foo();
|
|---|
| 115 | int value() const { return val; }
|
|---|
| 116 | public slots:
|
|---|
| 117 | void setValue( int );
|
|---|
| 118 | signals:
|
|---|
| 119 | void valueChanged( int );
|
|---|
| 120 | private:
|
|---|
| 121 | int val;
|
|---|
| 122 | };
|
|---|
| 123 | </pre>
|
|---|
| 124 |
|
|---|
| 125 | <p> This class has the same internal state, and public methods to access the
|
|---|
| 126 | state, but in addition it has support for component programming using
|
|---|
| 127 | signals and slots: this class can tell the outside world that its state
|
|---|
| 128 | has changed by emitting a signal, <tt>valueChanged()</tt>, and it has
|
|---|
| 129 | a slot which other objects can send signals to.
|
|---|
| 130 | <p> All classes that contain signals or slots must mention Q_OBJECT in
|
|---|
| 131 | their declaration.
|
|---|
| 132 | <p> Slots are implemented by the application programmer.
|
|---|
| 133 | Here is a possible implementation of Foo::setValue():
|
|---|
| 134 | <p> <pre>
|
|---|
| 135 | void Foo::setValue( int v )
|
|---|
| 136 | {
|
|---|
| 137 | if ( v != val ) {
|
|---|
| 138 | val = v;
|
|---|
| 139 | emit valueChanged(v);
|
|---|
| 140 | }
|
|---|
| 141 | }
|
|---|
| 142 | </pre>
|
|---|
| 143 |
|
|---|
| 144 | <p> The line <tt>emit valueChanged(v)</tt> emits the signal
|
|---|
| 145 | <tt>valueChanged</tt> from the object. As you can see, you emit a
|
|---|
| 146 | signal by using <tt>emit signal(arguments)</tt>.
|
|---|
| 147 | <p> Here is one way to connect two of these objects together:
|
|---|
| 148 | <p> <pre>
|
|---|
| 149 | Foo a, b;
|
|---|
| 150 | connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));
|
|---|
| 151 | b.setValue( 11 ); // a == undefined b == 11
|
|---|
| 152 | a.setValue( 79 ); // a == 79 b == 79
|
|---|
| 153 | b.value(); // returns 79
|
|---|
| 154 | </pre>
|
|---|
| 155 |
|
|---|
| 156 | <p> Calling <tt>a.setValue(79)</tt> will make <tt>a</tt> emit a <tt>valueChanged()</tt>
|
|---|
| 157 | signal, which <tt>b</tt> will receive in its <tt>setValue()</tt> slot,
|
|---|
| 158 | i.e. <tt>b.setValue(79)</tt> is called. <tt>b</tt> will then, in turn,
|
|---|
| 159 | emit the same <tt>valueChanged()</tt> signal, but since no slot has been
|
|---|
| 160 | connected to <tt>b</tt>'s <tt>valueChanged()</tt> signal, nothing happens (the
|
|---|
| 161 | signal is ignored).
|
|---|
| 162 | <p> Note that the <tt>setValue()</tt> function sets the value and emits
|
|---|
| 163 | the signal only if <tt>v != val</tt>. This prevents infinite looping
|
|---|
| 164 | in the case of cyclic connections (e.g. if <tt>b.valueChanged()</tt>
|
|---|
| 165 | were connected to <tt>a.setValue()</tt>).
|
|---|
| 166 | <p> A signal is emitted for <em>every</em> connection you make, so if you
|
|---|
| 167 | duplicate a connection, two signals will be emitted. You can always
|
|---|
| 168 | break a connection using <a href="qobject.html#disconnect">QObject::disconnect</a>().
|
|---|
| 169 | <p> This example illustrates that objects can work together without knowing
|
|---|
| 170 | about each other, as long as there is someone around to set up a
|
|---|
| 171 | connection between them initially.
|
|---|
| 172 | <p> The preprocessor changes or removes the <tt>signals</tt>, <tt>slots</tt> and
|
|---|
| 173 | <tt>emit</tt> keywords so that the compiler is presented with standard C++.
|
|---|
| 174 | <p> Run the <a href="moc.html">moc</a> on class definitions that contain
|
|---|
| 175 | signals or slots. This produces a C++ source file which should be compiled
|
|---|
| 176 | and linked with the other object files for the application. If you use
|
|---|
| 177 | <a href="qmake-manual.html">qmake</a>, the makefile rules to
|
|---|
| 178 | automatically invoke the <a href="moc.html">moc</a> will be added to
|
|---|
| 179 | your makefile for you.
|
|---|
| 180 | <p> <h2> Signals
|
|---|
| 181 | </h2>
|
|---|
| 182 | <a name="2"></a><p> Signals are emitted by an object when its internal state has changed
|
|---|
| 183 | in some way that might be interesting to the object's client or owner.
|
|---|
| 184 | Only the class that defines a signal and its subclasses can emit the
|
|---|
| 185 | signal.
|
|---|
| 186 | <p> A list box, for example, emits both <tt>clicked()</tt> and
|
|---|
| 187 | <tt>currentChanged()</tt> signals. Most objects will probably only be
|
|---|
| 188 | interested in <tt>currentChanged()</tt> which gives the current list item
|
|---|
| 189 | whether the user clicked it or used the arrow keys to move to it. But
|
|---|
| 190 | some objects may only want to know which item was clicked. If the
|
|---|
| 191 | signal is interesting to two different objects you just connect the
|
|---|
| 192 | signal to slots in both objects.
|
|---|
| 193 | <p> When a signal is emitted, the slots connected to it are executed
|
|---|
| 194 | immediately, just like a normal function call. The signal/slot
|
|---|
| 195 | mechanism is totally independent of any GUI event loop. The
|
|---|
| 196 | <tt>emit</tt> will return when all slots have returned.
|
|---|
| 197 | <p> If several slots are connected to one signal, the slots will be
|
|---|
| 198 | executed one after the other, in an arbitrary order, when the signal
|
|---|
| 199 | is emitted.
|
|---|
| 200 | <p> Signals are automatically generated by the <a href="moc.html">moc</a>
|
|---|
| 201 | and must not be implemented in the <tt>.cpp</tt> file. They can never have
|
|---|
| 202 | return types (i.e. use <tt>void</tt>).
|
|---|
| 203 | <p> A note about arguments. Our experience shows that signals and slots
|
|---|
| 204 | are more reusable if they do <em>not</em> use special types. If <a href="qscrollbar.html#valueChanged">QScrollBar::valueChanged</a>() were to use a special type such as the
|
|---|
| 205 | hypothetical <tt>QRangeControl::Range</tt>, it could only be connected to
|
|---|
| 206 | slots designed specifically for <a href="qrangecontrol.html">QRangeControl</a>. Something as simple as
|
|---|
| 207 | the program in <a href="tutorial1-05.html">Tutorial #1 part 5</a>
|
|---|
| 208 | would be impossible.
|
|---|
| 209 | <p> <h2> Slots
|
|---|
| 210 | </h2>
|
|---|
| 211 | <a name="3"></a><p> A slot is called when a signal connected to it is emitted. Slots are
|
|---|
| 212 | normal C++ functions and can be called normally; their only special
|
|---|
| 213 | feature is that signals can be connected to them. A slot's arguments
|
|---|
| 214 | cannot have default values, and, like signals, it is rarely wise to
|
|---|
| 215 | use your own custom types for slot arguments.
|
|---|
| 216 | <p> Since slots are normal member functions with just a little extra
|
|---|
| 217 | spice, they have access rights like ordinary member functions. A
|
|---|
| 218 | slot's access right determines who can connect to it:
|
|---|
| 219 | <p> A <tt>public slots</tt> section contains slots that anyone can connect
|
|---|
| 220 | signals to. This is very useful for component programming: you create
|
|---|
| 221 | objects that know nothing about each other, connect their signals and
|
|---|
| 222 | slots so that information is passed correctly, and, like a model
|
|---|
| 223 | railway, turn it on and leave it running.
|
|---|
| 224 | <p> A <tt>protected slots</tt> section contains slots that this class and its
|
|---|
| 225 | subclasses may connect signals to. This is intended for slots that are
|
|---|
| 226 | part of the class's implementation rather than its interface to the
|
|---|
| 227 | rest of the world.
|
|---|
| 228 | <p> A <tt>private slots</tt> section contains slots that only the class itself
|
|---|
| 229 | may connect signals to. This is intended for very tightly connected
|
|---|
| 230 | classes, where even subclasses aren't trusted to get the connections
|
|---|
| 231 | right.
|
|---|
| 232 | <p> You can also define slots to be virtual, which we have found quite
|
|---|
| 233 | useful in practice.
|
|---|
| 234 | <p> The signals and slots mechanism is efficient, but not quite as fast as
|
|---|
| 235 | "real" callbacks. Signals and slots are slightly slower because of the
|
|---|
| 236 | increased flexibility they provide, although the difference for real
|
|---|
| 237 | applications is insignificant. In general, emitting a signal that is
|
|---|
| 238 | connected to some slots, is approximately ten times slower than
|
|---|
| 239 | calling the receivers directly, with non-virtual function calls. This
|
|---|
| 240 | is the overhead required to locate the connection object, to safely
|
|---|
| 241 | iterate over all connections (i.e. checking that subsequent receivers
|
|---|
| 242 | have not been destroyed during the emission) and to marshall any
|
|---|
| 243 | parameters in a generic fashion. While ten non-virtual function calls
|
|---|
| 244 | may sound like a lot, it's much less overhead than any 'new' or
|
|---|
| 245 | 'delete' operation, for example. As soon as you perform a string,
|
|---|
| 246 | vector or list operation that behind the scene requires 'new' or
|
|---|
| 247 | 'delete', the signals and slots overhead is only responsible for a
|
|---|
| 248 | very small proportion of the complete function call costs. The same is
|
|---|
| 249 | true whenever you do a system call in a slot; or indirectly call more
|
|---|
| 250 | than ten functions. On an i586-500, you can emit around 2,000,000
|
|---|
| 251 | signals per second connected to one receiver, or around 1,200,000 per
|
|---|
| 252 | second connected to two receivers. The simplicity and flexibility of
|
|---|
| 253 | the signals and slots mechanism is well worth the overhead, which your
|
|---|
| 254 | users won't even notice.
|
|---|
| 255 | <p> <h2> Meta Object Information
|
|---|
| 256 | </h2>
|
|---|
| 257 | <a name="4"></a><p> The <a href="metaobjects.html#meta-object">meta object</a> compiler (<a href="moc.html"><a href="moc.html#moc">moc</a></a>) parses the class
|
|---|
| 258 | declaration in a C++ file and generates C++ code that initializes the
|
|---|
| 259 | meta object. The meta object contains the names of all the signal and
|
|---|
| 260 | slot members, as well as pointers to these functions. (For more
|
|---|
| 261 | information on Qt's Meta Object System, see <a href="templates.html">Why
|
|---|
| 262 | doesn't Qt use templates for signals and slots?</a>.)
|
|---|
| 263 | <p> The meta object contains additional information such as the object's <a href="qobject.html#className">class name</a>. You can also check if an object
|
|---|
| 264 | <a href="qobject.html#inherits">inherits</a> a specific class, for example:
|
|---|
| 265 | <p> <pre>
|
|---|
| 266 | if ( widget->inherits("QButton") ) {
|
|---|
| 267 | // yes, it is a push button, radio button etc.
|
|---|
| 268 | }
|
|---|
| 269 | </pre>
|
|---|
| 270 |
|
|---|
| 271 | <p> <h2> A Real Example
|
|---|
| 272 | </h2>
|
|---|
| 273 | <a name="5"></a><p> Here is a simple commented example (code fragments from <a href="qlcdnumber-h.html">qlcdnumber.h</a> ).
|
|---|
| 274 | <p> <pre>
|
|---|
| 275 | #include "qframe.h"
|
|---|
| 276 | #include "qbitarray.h"
|
|---|
| 277 |
|
|---|
| 278 | class QLCDNumber : public <a href="qframe.html">QFrame</a>
|
|---|
| 279 | </pre>
|
|---|
| 280 |
|
|---|
| 281 | <p> <a href="qlcdnumber.html">QLCDNumber</a> inherits <a href="qobject.html">QObject</a>, which has most of the signal/slot
|
|---|
| 282 | knowledge, via <a href="qframe.html">QFrame</a> and <a href="qwidget.html">QWidget</a>, and #include's the relevant
|
|---|
| 283 | declarations.
|
|---|
| 284 | <p> <pre>
|
|---|
| 285 | {
|
|---|
| 286 | Q_OBJECT
|
|---|
| 287 | </pre>
|
|---|
| 288 |
|
|---|
| 289 | <p> Q_OBJECT is expanded by the preprocessor to declare several member
|
|---|
| 290 | functions that are implemented by the moc; if you get compiler errors
|
|---|
| 291 | along the lines of "virtual function QButton::className not defined"
|
|---|
| 292 | you have probably forgotten to <a href="moc.html">run the moc</a> or to
|
|---|
| 293 | include the moc output in the link command.
|
|---|
| 294 | <p> <pre>
|
|---|
| 295 | public:
|
|---|
| 296 | <a href="qlcdnumber.html">QLCDNumber</a>( <a href="qwidget.html">QWidget</a> *parent=0, const char *name=0 );
|
|---|
| 297 | QLCDNumber( uint numDigits, QWidget *parent=0, const char *name=0 );
|
|---|
| 298 | </pre>
|
|---|
| 299 |
|
|---|
| 300 | <p> It's not obviously relevant to the moc, but if you inherit QWidget you
|
|---|
| 301 | almost certainly want to have the <em>parent</em> and <em>name</em>
|
|---|
| 302 | arguments in your constructors, and pass them to the parent
|
|---|
| 303 | constructor.
|
|---|
| 304 | <p> Some destructors and member functions are omitted here; the moc
|
|---|
| 305 | ignores member functions.
|
|---|
| 306 | <p> <pre>
|
|---|
| 307 | signals:
|
|---|
| 308 | void overflow();
|
|---|
| 309 | </pre>
|
|---|
| 310 |
|
|---|
| 311 | <p> <a href="qlcdnumber.html">QLCDNumber</a> emits a signal when it is asked to show an impossible
|
|---|
| 312 | value.
|
|---|
| 313 | <p> If you don't care about overflow, or you know that overflow cannot
|
|---|
| 314 | occur, you can ignore the overflow() signal, i.e. don't connect it to
|
|---|
| 315 | any slot.
|
|---|
| 316 | <p> If, on the other hand, you want to call two different error functions
|
|---|
| 317 | when the number overflows, simply connect the signal to two different
|
|---|
| 318 | slots. Qt will call both (in arbitrary order).
|
|---|
| 319 | <p> <pre>
|
|---|
| 320 | public slots:
|
|---|
| 321 | void display( int num );
|
|---|
| 322 | void display( double num );
|
|---|
| 323 | void display( const char *str );
|
|---|
| 324 | void setHexMode();
|
|---|
| 325 | void setDecMode();
|
|---|
| 326 | void setOctMode();
|
|---|
| 327 | void setBinMode();
|
|---|
| 328 | void smallDecimalPoint( bool );
|
|---|
| 329 | </pre>
|
|---|
| 330 |
|
|---|
| 331 | <p> A slot is a receiving function, used to get information about state
|
|---|
| 332 | changes in other widgets. QLCDNumber uses it, as the code above
|
|---|
| 333 | indicates, to set the displayed number. Since <tt>display()</tt> is part
|
|---|
| 334 | of the class's interface with the rest of the program, the slot is
|
|---|
| 335 | public.
|
|---|
| 336 | <p> Several of the example programs connect the newValue() signal of a
|
|---|
| 337 | <a href="qscrollbar.html">QScrollBar</a> to the display() slot, so the LCD number continuously shows
|
|---|
| 338 | the value of the scroll bar.
|
|---|
| 339 | <p> Note that display() is overloaded; Qt will select the appropriate version
|
|---|
| 340 | when you connect a signal to the slot. With callbacks, you'd have to find
|
|---|
| 341 | five different names and keep track of the types yourself.
|
|---|
| 342 | <p> Some irrelevant member functions have been omitted from this
|
|---|
| 343 | example.
|
|---|
| 344 | <p> <pre>
|
|---|
| 345 | };
|
|---|
| 346 | </pre>
|
|---|
| 347 |
|
|---|
| 348 | <p>
|
|---|
| 349 | <!-- eof -->
|
|---|
| 350 | <p><address><hr><div align=center>
|
|---|
| 351 | <table width=100% cellspacing=0 border=0><tr>
|
|---|
| 352 | <td>Copyright © 2007
|
|---|
| 353 | <a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
|
|---|
| 354 | <td align=right><div align=right>Qt 3.3.8</div>
|
|---|
| 355 | </table></div></address></body>
|
|---|
| 356 | </html>
|
|---|