diff options
Diffstat (limited to 'doc/src/corelib/objectmodel/signalsandslots.qdoc')
-rw-r--r-- | doc/src/corelib/objectmodel/signalsandslots.qdoc | 468 |
1 files changed, 0 insertions, 468 deletions
diff --git a/doc/src/corelib/objectmodel/signalsandslots.qdoc b/doc/src/corelib/objectmodel/signalsandslots.qdoc deleted file mode 100644 index 9100980121..0000000000 --- a/doc/src/corelib/objectmodel/signalsandslots.qdoc +++ /dev/null @@ -1,468 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page signalsandslots.html - \title Signals & Slots - \ingroup qt-basic-concepts - \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()}). - - By default, for every connection you make, a signal is emitted; - two signals are emitted for duplicate connections. You can break - all of these connections with a single disconnect() call. - If you pass the Qt::UniqueConnection \a type, the connection will only - be made if it is not a duplicate. If there is already a duplicate - (exact same signal to the exact same slot on the same objects), - the connection will fail and connect will return false - - 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. - Signals are public access functions and can be emitted from anywhere, - but we recommend to only emit them from the class that defines the - signal and its subclasses. - - 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 the order they have been connected, - 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. - 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 the order they were connected). - - \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 Signals And Slots With Default Arguments - - The signatures of signals and slots may contain arguments, and the - arguments can have default values. Consider QObject::destroyed(): - - \code - void destroyed(QObject* = 0); - \endcode - - When a QObject is deleted, it emits this QObject::destroyed() - signal. We want to catch this signal, wherever we might have a - dangling reference to the deleted QObject, so we can clean it up. - A suitable slot signature might be: - - \code - void objectDestroyed(QObject* obj = 0); - \endcode - - To connect the signal to the slot, we use QObject::connect(). - There are several ways to connect signal and slots. The first is to use - function pointers: - \code - connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed); - \endcode - - There are several advantages to using connect() with function pointers. - First, it allows the compiler to check that the signal's arguments are - compatible with the slot's arguments. Arguments can also be implicitly - converted by the compiler, if needed. - - You can also connect to functors or C++11 lamdas: - - \code - connect(sender, &QObject::destroyed, [=](){ this->m_objects.remove(sender); }); - \endcode - - Note that if your compiler does not support C++11 variadic templates, - this syntax only works if the signal and slot have 6 arguments or less. - - The other way to connect a signal to a slot is to use QObject::connect() - and the \c{SIGNAL} and \c{SLOT} macros. - The rule about whether to - include arguments or not in the \c{SIGNAL()} and \c{SLOT()} - macros, if the arguments have default values, is that the - signature passed to the \c{SIGNAL()} macro must \e not have fewer - arguments than the signature passed to the \c{SLOT()} macro. - - All of these would work: - \code - connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*))); - connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed())); - connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed())); - \endcode - But this one won't work: - \code - connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*))); - \endcode - - ...because the slot will be expecting a QObject that the signal - will not send. This connection will report a runtime error. - - Note that signal and slot arguments are not checked by the compiler when - using this QObject::connect() overload. - - \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.cpp 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. -*/ |