diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
commit | bd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch) | |
tree | 7a520322212d48ebcb9fbe1087e7fca28b76185c /doc/html/signalsandslots.html | |
download | qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip |
Add Qt3 development HEAD version
Diffstat (limited to 'doc/html/signalsandslots.html')
-rw-r--r-- | doc/html/signalsandslots.html | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/doc/html/signalsandslots.html b/doc/html/signalsandslots.html new file mode 100644 index 0000000..d5e1ee7 --- /dev/null +++ b/doc/html/signalsandslots.html @@ -0,0 +1,356 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/signalsandslots.doc:36 --> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Signals and Slots</title> +<style type="text/css"><!-- +fn { margin-left: 1cm; text-indent: -1cm; } +a:link { color: #004faf; text-decoration: none } +a:visited { color: #672967; text-decoration: none } +body { background: #ffffff; color: black; } +--></style> +</head> +<body> + +<table border="0" cellpadding="0" cellspacing="0" width="100%"> +<tr bgcolor="#E5E5E5"> +<td valign=center> + <a href="index.html"> +<font color="#004faf">Home</font></a> + | <a href="classes.html"> +<font color="#004faf">All Classes</font></a> + | <a href="mainclasses.html"> +<font color="#004faf">Main Classes</font></a> + | <a href="annotated.html"> +<font color="#004faf">Annotated</font></a> + | <a href="groups.html"> +<font color="#004faf">Grouped Classes</font></a> + | <a href="functions.html"> +<font color="#004faf">Functions</font></a> +</td> +<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> + + +<p> Signals and slots are used for communication between objects. The +signal/slot mechanism is a central feature of Qt and probably the +part that differs most from other toolkits. +<p> In GUI programming we often want a change in one widget to be notified +to another widget. More generally, we want objects of any kind to be +able to communicate with one another. For example if we were parsing +an XML file we might want to notify a list view that we're using to +represent the XML file's structure whenever we encounter a new tag. +<p> Older toolkits achieve this kind of communication using callbacks. A +callback is a pointer to a function, so if you want a processing +function to notify you about some event you pass a pointer to another +function (the callback) to the processing function. The processing +function then calls the callback when appropriate. Callbacks have two +fundamental flaws. Firstly they are not type safe. We can never be +certain that the processing function will call the callback with the +correct arguments. Secondly the callback is strongly coupled to the +processing function since the processing function must know which +callback to call. +<p> <center><img src="abstract-connections.png"></center> <blockquote><p align="center"><em> An abstract view of some signals and slots connections +</em></p> +</blockquote><p> In Qt we have an alternative to the callback technique. We use signals +and slots. A signal is emitted when a particular event occurs. Qt's +widgets have many pre-defined signals, but we can always subclass to +add our own. A slot is a function that is called in reponse to a +particular signal. Qt's widgets have many pre-defined slots, but it is +common practice to add your own slots so that you can handle the +signals that you are interested in. +<p> The signals and slots mechanism is type safe: the signature of a +signal must match the signature of the receiving slot. (In fact a slot +may have a shorter signature than the signal it receives because it +can ignore extra arguments.) Since the signatures are compatible, the +compiler can help us detect type mismatches. Signals and slots are +loosely coupled: a class which emits a signal neither knows nor cares +which slots receive the signal. Qt's signals and slots mechanism +ensures that if you connect a signal to a slot, the slot will be +called with the signal's parameters at the right time. Signals and +slots can take any number of arguments of any type. They are +completely typesafe: no more callback core dumps! +<p> All classes that inherit from <a href="qobject.html">QObject</a> or one of its subclasses +(e.g. <a href="qwidget.html">QWidget</a>) can contain signals and slots. Signals are emitted by +objects when they change their state in a way that may be interesting +to the outside world. This is all the object does to communicate. It +does not know or care whether anything is receiving the signals it +emits. This is true information encapsulation, and ensures that the +object can be used as a software component. +<p> <center><img src="concrete-connections.png"></center> <blockquote><p align="center"><em> An example of signals and slots connections +</em></p> +</blockquote><p> Slots can be used for receiving signals, but they are also normal +member functions. Just as an object does not know if anything receives +its signals, a slot does not know if it has any signals connected to +it. This ensures that truly independent components can be created with +Qt. +<p> You can connect as many signals as you want to a single slot, and a +signal can be connected to as many slots as you desire. It is even +possible to connect a signal directly to another signal. (This will +emit the second signal immediately whenever the first is emitted.) +<p> Together, signals and slots make up a powerful component programming +mechanism. +<p> <h2> A Small Example +</h2> +<a name="1"></a><p> A minimal C++ class declaration might read: +<p> <pre> + class Foo + { + public: + Foo(); + int value() const { return val; } + void setValue( int ); + private: + int val; + }; +</pre> + +<p> A small Qt class might read: +<p> <pre> + class Foo : public <a href="qobject.html">QObject</a> + { + <a href="metaobjects.html#Q_OBJECT">Q_OBJECT</a> + public: + Foo(); + int value() const { return val; } + public slots: + void setValue( int ); + signals: + void valueChanged( int ); + private: + int val; + }; +</pre> + +<p> This class has the same internal state, and public methods to access the +state, but in addition it has support for component programming using +signals and slots: this class can tell the outside world that its state +has changed by emitting a signal, <tt>valueChanged()</tt>, and it has +a slot which other objects can send signals to. +<p> All classes that contain signals or slots must mention Q_OBJECT in +their declaration. +<p> Slots are implemented by the application programmer. +Here is a possible implementation of Foo::setValue(): +<p> <pre> + void Foo::setValue( int v ) + { + if ( v != val ) { + val = v; + emit valueChanged(v); + } + } +</pre> + +<p> The line <tt>emit valueChanged(v)</tt> emits the signal +<tt>valueChanged</tt> from the object. As you can see, you emit a +signal by using <tt>emit signal(arguments)</tt>. +<p> Here is one way to connect two of these objects together: +<p> <pre> + Foo a, b; + connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int))); + b.setValue( 11 ); // a == undefined b == 11 + a.setValue( 79 ); // a == 79 b == 79 + b.value(); // returns 79 +</pre> + +<p> Calling <tt>a.setValue(79)</tt> will make <tt>a</tt> emit a <tt>valueChanged()</tt> +signal, which <tt>b</tt> will receive in its <tt>setValue()</tt> slot, +i.e. <tt>b.setValue(79)</tt> is called. <tt>b</tt> will then, in turn, +emit the same <tt>valueChanged()</tt> signal, but since no slot has been +connected to <tt>b</tt>'s <tt>valueChanged()</tt> signal, nothing happens (the +signal is ignored). +<p> Note that the <tt>setValue()</tt> function sets the value and emits +the signal only if <tt>v != val</tt>. This prevents infinite looping +in the case of cyclic connections (e.g. if <tt>b.valueChanged()</tt> +were connected to <tt>a.setValue()</tt>). +<p> A signal is emitted for <em>every</em> connection you make, so if you +duplicate a connection, two signals will be emitted. You can always +break a connection using <a href="qobject.html#disconnect">QObject::disconnect</a>(). +<p> This example illustrates that objects can work together without knowing +about each other, as long as there is someone around to set up a +connection between them initially. +<p> The preprocessor changes or removes the <tt>signals</tt>, <tt>slots</tt> and +<tt>emit</tt> keywords so that the compiler is presented with standard C++. +<p> Run the <a href="moc.html">moc</a> on class definitions that contain +signals or slots. This produces a C++ source file which should be compiled +and linked with the other object files for the application. If you use +<a href="qmake-manual.html">qmake</a>, the makefile rules to +automatically invoke the <a href="moc.html">moc</a> will be added to +your makefile for you. +<p> <h2> Signals +</h2> +<a name="2"></a><p> Signals are emitted by an object when its internal state has changed +in some way that might be interesting to the object's client or owner. +Only the class that defines a signal and its subclasses can emit the +signal. +<p> A list box, for example, emits both <tt>clicked()</tt> and +<tt>currentChanged()</tt> signals. Most objects will probably only be +interested in <tt>currentChanged()</tt> which gives the current list item +whether the user clicked it or used the arrow keys to move to it. But +some objects may only want to know which item was clicked. If the +signal is interesting to two different objects you just connect the +signal to slots in both objects. +<p> When a signal is emitted, the slots connected to it are executed +immediately, just like a normal function call. The signal/slot +mechanism is totally independent of any GUI event loop. The +<tt>emit</tt> will return when all slots have returned. +<p> If several slots are connected to one signal, the slots will be +executed one after the other, in an arbitrary order, when the signal +is emitted. +<p> Signals are automatically generated by the <a href="moc.html">moc</a> +and must not be implemented in the <tt>.cpp</tt> file. They can never have +return types (i.e. use <tt>void</tt>). +<p> A note about arguments. Our experience shows that signals and slots +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 +hypothetical <tt>QRangeControl::Range</tt>, it could only be connected to +slots designed specifically for <a href="qrangecontrol.html">QRangeControl</a>. Something as simple as +the program in <a href="tutorial1-05.html">Tutorial #1 part 5</a> +would be impossible. +<p> <h2> Slots +</h2> +<a name="3"></a><p> A slot is called when a signal connected to it is emitted. Slots are +normal C++ functions and can be called normally; their only special +feature is that signals can be connected to them. A slot's arguments +cannot have default values, and, like signals, it is rarely wise to +use your own custom types for slot arguments. +<p> Since slots are normal member functions with just a little extra +spice, they have access rights like ordinary member functions. A +slot's access right determines who can connect to it: +<p> A <tt>public slots</tt> section contains slots that anyone can connect +signals to. This is very useful for component programming: you create +objects that know nothing about each other, connect their signals and +slots so that information is passed correctly, and, like a model +railway, turn it on and leave it running. +<p> A <tt>protected slots</tt> section contains slots that this class and its +subclasses may connect signals to. This is intended for slots that are +part of the class's implementation rather than its interface to the +rest of the world. +<p> A <tt>private slots</tt> section contains slots that only the class itself +may connect signals to. This is intended for very tightly connected +classes, where even subclasses aren't trusted to get the connections +right. +<p> You can also define slots to be virtual, which we have found quite +useful in practice. +<p> The signals and slots mechanism is efficient, but not quite as fast as +"real" callbacks. Signals and slots are slightly slower because of the +increased flexibility they provide, although the difference for real +applications is insignificant. In general, emitting a signal that is +connected to some slots, is approximately ten times slower than +calling the receivers directly, with non-virtual function calls. This +is the overhead required to locate the connection object, to safely +iterate over all connections (i.e. checking that subsequent receivers +have not been destroyed during the emission) and to marshall any +parameters in a generic fashion. While ten non-virtual function calls +may sound like a lot, it's much less overhead than any 'new' or +'delete' operation, for example. As soon as you perform a string, +vector or list operation that behind the scene requires 'new' or +'delete', the signals and slots overhead is only responsible for a +very small proportion of the complete function call costs. The same is +true whenever you do a system call in a slot; or indirectly call more +than ten functions. On an i586-500, you can emit around 2,000,000 +signals per second connected to one receiver, or around 1,200,000 per +second connected to two receivers. The simplicity and flexibility of +the signals and slots mechanism is well worth the overhead, which your +users won't even notice. +<p> <h2> Meta Object Information +</h2> +<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 +declaration in a C++ file and generates C++ code that initializes the +meta object. The meta object contains the names of all the signal and +slot members, as well as pointers to these functions. (For more +information on Qt's Meta Object System, see <a href="templates.html">Why +doesn't Qt use templates for signals and slots?</a>.) +<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 +<a href="qobject.html#inherits">inherits</a> a specific class, for example: +<p> <pre> + if ( widget->inherits("QButton") ) { + // yes, it is a push button, radio button etc. + } +</pre> + +<p> <h2> A Real Example +</h2> +<a name="5"></a><p> Here is a simple commented example (code fragments from <a href="qlcdnumber-h.html">qlcdnumber.h</a> ). +<p> <pre> + #include "qframe.h" + #include "qbitarray.h" + + class QLCDNumber : public <a href="qframe.html">QFrame</a> +</pre> + +<p> <a href="qlcdnumber.html">QLCDNumber</a> inherits <a href="qobject.html">QObject</a>, which has most of the signal/slot +knowledge, via <a href="qframe.html">QFrame</a> and <a href="qwidget.html">QWidget</a>, and #include's the relevant +declarations. +<p> <pre> + { + Q_OBJECT +</pre> + +<p> Q_OBJECT is expanded by the preprocessor to declare several member +functions that are implemented by the moc; if you get compiler errors +along the lines of "virtual function QButton::className not defined" +you have probably forgotten to <a href="moc.html">run the moc</a> or to +include the moc output in the link command. +<p> <pre> + public: + <a href="qlcdnumber.html">QLCDNumber</a>( <a href="qwidget.html">QWidget</a> *parent=0, const char *name=0 ); + QLCDNumber( uint numDigits, QWidget *parent=0, const char *name=0 ); +</pre> + +<p> It's not obviously relevant to the moc, but if you inherit QWidget you +almost certainly want to have the <em>parent</em> and <em>name</em> +arguments in your constructors, and pass them to the parent +constructor. +<p> Some destructors and member functions are omitted here; the moc +ignores member functions. +<p> <pre> + signals: + void overflow(); +</pre> + +<p> <a href="qlcdnumber.html">QLCDNumber</a> emits a signal when it is asked to show an impossible +value. +<p> If you don't care about overflow, or you know that overflow cannot +occur, you can ignore the overflow() signal, i.e. don't connect it to +any slot. +<p> If, on the other hand, you want to call two different error functions +when the number overflows, simply connect the signal to two different +slots. Qt will call both (in arbitrary order). +<p> <pre> + public slots: + void display( int num ); + void display( double num ); + void display( const char *str ); + void setHexMode(); + void setDecMode(); + void setOctMode(); + void setBinMode(); + void smallDecimalPoint( bool ); +</pre> + +<p> A slot is a receiving function, used to get information about state +changes in other widgets. QLCDNumber uses it, as the code above +indicates, to set the displayed number. Since <tt>display()</tt> is part +of the class's interface with the rest of the program, the slot is +public. +<p> Several of the example programs connect the newValue() signal of a +<a href="qscrollbar.html">QScrollBar</a> to the display() slot, so the LCD number continuously shows +the value of the scroll bar. +<p> Note that display() is overloaded; Qt will select the appropriate version +when you connect a signal to the slot. With callbacks, you'd have to find +five different names and keep track of the types yourself. +<p> Some irrelevant member functions have been omitted from this +example. +<p> <pre> + }; +</pre> + +<p> +<!-- eof --> +<p><address><hr><div align=center> +<table width=100% cellspacing=0 border=0><tr> +<td>Copyright © 2007 +<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a> +<td align=right><div align=right>Qt 3.3.8</div> +</table></div></address></body> +</html> |