summaryrefslogtreecommitdiffstats
path: root/doc/src/signalsandslots.qdoc
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 09:18:55 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 09:18:55 (GMT)
commite5fcad302d86d316390c6b0f62759a067313e8a9 (patch)
treec2afbf6f1066b6ce261f14341cf6d310e5595bc1 /doc/src/signalsandslots.qdoc
downloadQt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip
Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz
Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2
Long live Qt 4.5!
Diffstat (limited to 'doc/src/signalsandslots.qdoc')
-rw-r--r--doc/src/signalsandslots.qdoc418
1 files changed, 418 insertions, 0 deletions
diff --git a/doc/src/signalsandslots.qdoc b/doc/src/signalsandslots.qdoc
new file mode 100644
index 0000000..5432bd4
--- /dev/null
+++ b/doc/src/signalsandslots.qdoc
@@ -0,0 +1,418 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page signalsandslots.html
+ \title Signals and Slots
+ \ingroup architecture
+ \brief An overview of Qt's signals and slots inter-object
+ communication mechanism.
+
+ Signals and slots are used for communication between objects. The
+ signals and slots mechanism is a central feature of Qt and
+ probably the part that differs most from the features provided by
+ other frameworks.
+
+ \tableofcontents
+
+ \section1 Introduction
+
+ In GUI programming, when we change one widget, we often want
+ another widget to be notified. More generally, we want objects of
+ any kind to be able to communicate with one another. For example,
+ if a user clicks a \gui{Close} button, we probably want the
+ window's \l{QWidget::close()}{close()} function to be called.
+
+ 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.
+
+ \section1 Signals and Slots
+
+ 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 predefined signals, but we can
+ always subclass widgets to add our own signals to them. A slot
+ is a function that is called in response to a particular signal.
+ Qt's widgets have many pre-defined slots, but it is common
+ practice to subclass widgets and add your own slots so that you
+ can handle the signals that you are interested in.
+
+ \img abstract-connections.png
+ \omit
+ \caption An abstract view of some signals and slots connections
+ \endomit
+
+ 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 type safe.
+
+ All classes that inherit from QObject or one of its subclasses
+ (e.g., QWidget) can contain signals and slots. Signals are emitted by
+ objects when they change their state in a way that may be interesting
+ to other objects. 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.
+
+ 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.
+
+ 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 need. It is even
+ possible to connect a signal directly to another signal. (This will
+ emit the second signal immediately whenever the first is emitted.)
+
+ Together, signals and slots make up a powerful component programming
+ mechanism.
+
+ \section1 A Small Example
+
+ A minimal C++ class declaration might read:
+
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.h 0
+
+ A small QObject-based class might read:
+
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.h 1
+ \codeline
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.h 2
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.h 3
+
+ The QObject-based version has the same internal state, and provides
+ 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, \c{valueChanged()}, and it has a slot which other objects
+ can send signals to.
+
+ All classes that contain signals or slots must mention
+ Q_OBJECT at the top of their declaration. They must also derive
+ (directly or indirectly) from QObject.
+
+ Slots are implemented by the application programmer.
+ Here is a possible implementation of the \c{Counter::setValue()}
+ slot:
+
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 0
+
+ The \c{emit} line emits the signal \c valueChanged() from the
+ object, with the new value as argument.
+
+ In the following code snippet, we create two \c Counter objects
+ and connect the first object's \c valueChanged() signal to the
+ second object's \c setValue() slot using QObject::connect():
+
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 1
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 2
+ \codeline
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 3
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 4
+
+ Calling \c{a.setValue(12)} makes \c{a} emit a
+ \c{valueChanged(12)} signal, which \c{b} will receive in its
+ \c{setValue()} slot, i.e. \c{b.setValue(12)} is called. Then
+ \c{b} emits the same \c{valueChanged()} signal, but since no slot
+ has been connected to \c{b}'s \c{valueChanged()} signal, the
+ signal is ignored.
+
+ Note that the \c{setValue()} function sets the value and emits
+ the signal only if \c{value != m_value}. This prevents infinite
+ looping in the case of cyclic connections (e.g., if
+ \c{b.valueChanged()} were connected to \c{a.setValue()}).
+
+ A signal is emitted for every connection you make; if you
+ duplicate a connection, two signals will be emitted. You can
+ always break a connection using QObject::disconnect().
+
+ This example illustrates that objects can work together without needing to
+ know any information about each other. To enable this, the objects only
+ need to be connected together, and this can be achieved with some simple
+ QObject::connect() function calls, or with \c{uic}'s
+ \l{Using a Designer .ui File in Your Application#Automatic Connections}
+ {automatic connections} feature.
+
+ \section1 Building the Example
+
+ The C++ preprocessor changes or removes the \c{signals},
+ \c{slots}, and \c{emit} keywords so that the compiler is
+ presented with standard C++.
+
+ By running the \l moc on class definitions that contain signals
+ or slots, a C++ source file is produced which should be compiled
+ and linked with the other object files for the application. If
+ you use \l qmake, the makefile rules to automatically invoke \c
+ moc will be added to your project's makefile.
+
+ \section1 Signals
+
+ 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.
+
+ When a signal is emitted, the slots connected to it are usually
+ executed immediately, just like a normal function call. When this
+ happens, the signals and slots mechanism is totally independent of
+ any GUI event loop. Execution of the code following the \c emit
+ statement will occur once all slots have returned. The situation is
+ slightly different when using \l{Qt::ConnectionType}{queued
+ connections}; in such a case, the code following the \c emit keyword
+ will continue immediately, and the slots will be executed later.
+
+ 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.
+
+ Signals are automatically generated by the \l moc and must not be
+ implemented in the \c .cpp file. They can never have return types
+ (i.e. use \c void).
+
+ A note about arguments: Our experience shows that signals and slots
+ are more reusable if they do not use special types. If
+ QScrollBar::valueChanged() were to use a special type such as the
+ hypothetical QScrollBar::Range, it could only be connected to
+ slots designed specifically for QScrollBar. Connecting different
+ input widgets together would be impossible.
+
+ \section1 Slots
+
+ 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.
+
+ Since slots are normal member functions, they follow the normal C++
+ rules when called directly. However, as slots, they can be invoked
+ by any component, regardless of its access level, via a signal-slot
+ connection. This means that a signal emitted from an instance of an
+ arbitrary class can cause a private slot to be invoked in an instance
+ of an unrelated class.
+
+ You can also define slots to be virtual, which we have found quite
+ useful in practice.
+
+ Compared to 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 \c
+ new or \c delete operation, for example. As soon as you perform a
+ string, vector or list operation that behind the scene requires
+ \c new or \c 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.
+
+ Note that other libraries that define variables called \c signals
+ or \c slots may cause compiler warnings and errors when compiled
+ alongside a Qt-based application. To solve this problem, \c
+ #undef the offending preprocessor symbol.
+
+ \section1 Meta-Object Information
+
+ The meta-object compiler (\l moc) 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.
+
+ The meta-object contains additional information such as the
+ object's \link QObject::className() class name\endlink. You can
+ also check if an object \link QObject::inherits()
+ inherits\endlink a specific class, for example:
+
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 5
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 6
+
+ The meta-object information is also used by qobject_cast<T>(), which
+ is similar to QObject::inherits() but is less error-prone:
+
+ \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 7
+
+ See \l{Meta-Object System} for more information.
+
+ \section1 A Real Example
+
+ Here is a simple commented example of a widget.
+
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 0
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 1
+ \codeline
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 2
+ \codeline
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 3
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 4
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 5
+
+ \c LcdNumber inherits QObject, which has most of the signal-slot
+ knowledge, via QFrame and QWidget. It is somewhat similar to the
+ built-in QLCDNumber widget.
+
+ The Q_OBJECT macro is expanded by the preprocessor to declare
+ several member functions that are implemented by the \c{moc}; if
+ you get compiler errors along the lines of "undefined reference
+ to vtable for \c{LcdNumber}", you have probably forgotten to
+ \l{moc}{run the moc} or to include the moc output in the link
+ command.
+
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 6
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 7
+
+ It's not obviously relevant to the moc, but if you inherit
+ QWidget you almost certainly want to have the \c parent argument
+ in your constructor and pass it to the base class's constructor.
+
+ Some destructors and member functions are omitted here; the \c
+ moc ignores member functions.
+
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 8
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 9
+
+ \c LcdNumber emits a signal when it is asked to show an impossible
+ value.
+
+ If you don't care about overflow, or you know that overflow
+ cannot occur, you can ignore the \c overflow() signal, i.e. don't
+ connect it to any slot.
+
+ 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).
+
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 10
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 11
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 12
+ \codeline
+ \snippet doc/src/snippets/signalsandslots/lcdnumber.h 13
+
+ A slot is a receiving function used to get information about
+ state changes in other widgets. \c LcdNumber uses it, as the code
+ above indicates, to set the displayed number. Since \c{display()}
+ is part of the class's interface with the rest of the program,
+ the slot is public.
+
+ Several of the example programs connect the
+ \l{QScrollBar::valueChanged()}{valueChanged()} signal of a
+ QScrollBar to the \c display() slot, so the LCD number
+ continuously shows the value of the scroll bar.
+
+ Note that \c 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.
+
+ Some irrelevant member functions have been omitted from this
+ example.
+
+ \section1 Advanced Signals and Slots Usage
+
+ For cases where you may require information on the sender of the
+ signal, Qt provides the QObject::sender() function, which returns
+ a pointer to the object that sent the signal.
+
+ The QSignalMapper class is provided for situations where many
+ signals are connected to the same slot and the slot needs to
+ handle each signal differently.
+
+ Suppose you have three push buttons that determine which file you
+ will open: "Tax File", "Accounts File", or "Report File".
+
+ In order to open the correct file, you use QSignalMapper::setMapping() to
+ map all the clicked() signals to a QSignalMapper object. Then you connect
+ the file's QPushButton::clicked() signal to the QSignalMapper::map() slot.
+
+ \snippet doc/src/snippets/signalmapper/filereader.cpp 0
+
+ Then, you connect the \l{QSignalMapper::}{mapped()} signal to
+ \c{readFile()} where a different file will be opened, depending on
+ which push button is pressed.
+
+ \snippet doc/src/snippets/signalmapper/filereader.cpp 1
+
+ \sa {Meta-Object System}, {Qt's Property System}
+
+ \target 3rd Party Signals and Slots
+ \section2 Using Qt with 3rd Party Signals and Slots
+
+ It is possible to use Qt with a 3rd party signal/slot mechanism.
+ You can even use both mechanisms in the same project. Just add the
+ following line to your qmake project (.pro) file.
+
+ \snippet doc/src/snippets/code/doc_src_containers.qdoc 22
+
+ It tells Qt not to define the moc keywords \c{signals}, \c{slots},
+ and \c{emit}, because these names will be used by a 3rd party
+ library, e.g. Boost. Then to continue using Qt signals and slots
+ with the \c{no_keywords} flag, simply replace all uses of the Qt
+ moc keywords in your sources with the corresponding Qt macros
+ Q_SIGNALS (or Q_SIGNAL), Q_SLOTS (or Q_SLOT), and Q_EMIT.
+*/