In graphic interface programming, we often want to notify another or several objects when a visual object changes, we hope that any class of objects can communicate with other objects. For example, a value display window is used to display the current value of a scroll bar object. When the value of the scroll bar object changes, we hope that the value display window will receive a "value change" signal from the scroll bar object to change its display value. For issues similar to the above, the earlier toolkit uses the "Callback" method. Callback refers to the pointer of a function. If you want a handler to handle some of your events, you can pass the pointer of another function to the handler. The handler will call the callback function when appropriate. There are two main disadvantages of implementing communication between objects through callback. First, the callback function is not of type security. We cannot be sure that the processing function uses the correct parameters to call the callback function. Second, the callback function is closely related to the processing function, because the processing function must know which callback function to call. In the QT development environment, we have a mechanism called "signal and slot" to implement communication between objects, which can replace callback functions. The signal and slot mechanism is used to implement communication between objects. It is a central feature of QT, and I am afraid it is the most different from other toolkit. The signal and slot mechanism are as follows: when a specific event occurs, one or more specified signals will be transmitted. The slot is a function that returns void, if one or several slots are connected to the signal, the (some) slot (function) will be executed immediately after the signal is sent. The signal and slot mechanism are type-safe. The signature of a signal must match the signature of its receiving slot, so that the compiler can help us check whether the type matches. The signal and the slot are very loose in connection with each other. A transmitting signal object does not need to consider which slot will receive the signal, the object where the receiving slot is located does not know which object the signal to connect is. The QT signal and slot mechanism ensure that if you connect a signal to a slot, the slot will be called using the signal parameters at the correct time, signal and slot can use any number or type of parameters. Qt's window components already have many predefined signals and many predefined slots, but we always add our own signals and slots through inheritance, in this way, we can process signals of interest. All classes inherited from the qobject class or its subclass can contain signals and slots. When an event occurs, the specified signal is sent. It does not know or need to know whether a slot is connected to the signal. This is information encapsulation. A slot is a member function of a normal object that can be used to receive signals. A slot does not know whether it is connected by other signals. You can connect a signal to a single slot. At this time, the slot will be executed because the signal is sent. You can also connect several signals to the same slot, in this way, any signal is transmitted, so that the slot is executed. You can also connect one signal and multiple slots, so that once the signal is transmitted, the connected slots will be executed immediately, but the execution sequence is uncertain and cannot be specified. You can also connect one signal to another, as long as the first signal is sent, the second signal is immediately sent. Next, let's take a look at the differences between the two objects that do not use signals and slots, and those that use signals and slots. C ++ objects without signals and slots: Class nosignalclass { Public: Nosignalclass (void ){} Int value (void) const {return _ value ;} Int setvalue (INT value) {_ value = value ;} PRIVATE: Int _ value; } Qt objects using signals and slots: Class usesignalclass { Q_object Public: Usesignalclass (void ){} Int value (void) const {return _ value ;} Public slots: Int setvalue (INT value) {_ value = value ;} Signals: Void valuechanged (INT ); PRIVATE: Int _ value; } These two classes have the same internal status and the same public method, but the latter class supports programming using the component of the signal and the slot: This class can transmit a signal (valuechanged ()) to tell the outside world that its status has changed, and it has a slot that can receive signals. All classes that contain signals and slots must mention q_object in their declaration. The slot should be implemented by itself. Here we 'd better implement the int setvalue (INT value) slot like this: Void usesignalclass: setvalue (INT value) { If (value! = _ Value ){ _ Val = value; Emit valuechanged (value ); } } Emit valuechanged (value); this line of code is to emit a signal valuechanged. To enable a slot to be executed after a signal is sent, connect it explicitly: Usesignalclass A, B; Connect (& A, signal (valuechanged (INT), & B, slot (setvalue (INT ))); After this is done, the valuechanged signal of object A is connected to the setvalue slot of object B. When the valuechanged signal of object A is transmitted, the setvalue slot of object B is immediately executed. Run the following code: B. setvalue (10 ); After this statement is executed, the valuechanged signal of object B will be sent, but there is no slot to connect to the signal, so nothing is done and the signal is discarded. A. setvalue (80 ); After this statement is executed, the valuechanged signal of object A will be sent, and the signal is connected by a slot (setvalue of object B), So B. setvalue (INT) is executed immediately and the parameter is 80, so B. the value () is 80. You can use the disconnect () function to remove signals and slots that have established connections. Bool qobject: disconnect (const qobject * sender, const char * signal, Const object * receiver, const char * member) [Static] This function disconnects the signal in the transmitter from the slot function in the receiver. There are three situations: 1. Disconnect an object from other objects: Disconnect (object, 0, 0, 0); or object-> disconnect (); 2. Disconnect a signal from any other slot: Disconnect (object, signal (), 0, 0); or object-> disconnect (signal ())); 3. Disconnect any association between two objects: Disconnect (object, 0, receiver, 0); or object-> disconnect (receiver ); In the disconnect function, 0 can be used as a wildcard to represent any signal, any receiving object, or any slot function in the receiving object. However, the initiator cannot be 0, and the other three parameters can be 0. The keyword signals indicates the subsequent declaration of the starting signal. Here, signals uses the form of plural instead of singular. siganls does not have attributes such as public, private, and protected, which is different from slots. In addition, the signals and slots keywords are defined by QT and are not keywords in C ++. This example shows that after using the QT signal and slot mechanism, objects can work together without knowing each other, as long as a connection is established between them at the beginning. The slot is also a common C ++ function and can be called. Its only feature is that they can be connected by signals. Because a slot is a common member function, it has the same access permission as a common member function. The access permission of a slot determines which signals can be connected to it, the signal has no access permission. A public slots: A zone contains a slot where any signal can be connected. You have generated many objects that do not know each other. They connect their signals to the slot so that information can be correctly transmitted, and they are like a railway model, open it and run it. A protected slots: The slots that can be connected only after the signal of this class and its subclass is included. This means that these slots are only part of the implementation of the class, rather than its external interfaces. A private slots: contains the slots that can be connected by signals of the class itself. This means that it is very closely related to this class, and even its sub-classes do not have the trust of connection rights. You can also define a slot as a virtual function, which is also useful. Note the following when using the signal and slot mechanism: 1. The signal and slot mechanism is very effective, but it is not as fast as the "real" callback. The signal and slot are a little slow because they provide flexibility. However, this loss is relatively small. However, to achieve high efficiency, such as using this mechanism as little as possible in real-time systems. 2. The signal and slot mechanism is the same as the call of common functions. If improperly used, an endless loop may be formed during program execution, when defining a slot function, be sure to avoid indirect infinite loops, that is, re-launch the same signal received in the slot. 3. If a signal is associated with multiple slots, when the signal is sent, the execution sequence of the slots associated with the signal will be from the marrow machine, and the sequence cannot be specified. 4. macro definitions cannot be used in parameters of signal and slot. 5. constructors cannot be used in the signals and slots declaration regions. 6. function pointers cannot be used as signal or slot parameters. 7. The default parameter values cannot be set for signals and slots. 8. The signal and slot cannot carry template parameters. 9. Nested classes cannot be located in the signal and slot areas, or have signals or slots. 10. The youyuan statement cannot be in the Declaration area of the signal and slot. |