QT is a cross-platform C ++ GUI application framework. It provides a rich set of window components and features object-oriented, easy to expand, and true component programming, even more striking is that the most popular KDE Desktop Environment on Linux is built on the basis of the QT library. Qt supports the following platforms: MS/Windows-95, 98, NT and 2000; UNIX/X11-Linux, Sun Solaris, HP-UX, Digital UNIX, ibm aix, sgi irix; embedded-Linux platform supporting framebuffer. With the rapid development and popularization of Kde, QT is likely to become the preferred GUI for software development on the Linux window platform.
Overview
The signal and slot mechanism is the core mechanism of QT. to be proficient in QT programming, you must have a good understanding of the signal and slot. The signal and slot are an advanced interface used for communication between objects. It is the core feature of QT and an important part of distinguishing QT from other toolkit. The signal and slot is a communication mechanism defined by QT. It is independent from the Standard C/C ++ language. Therefore, it is necessary to correctly process the signal and slot, you must use a QT tool called MOC (meta object compiler), which is a C ++ Preprocessing Program that automatically generates additional code for high-level event processing.
In many well-known GUI toolkits, Widgets have a callback function to respond to each action they can trigger, this callback function is usually a pointer to a function. However, in QT, CITIC signs and slots replace these messy function pointers, making these communication programs simpler and clearer. Signals and slots can carry any number and any type of parameters. They are completely type-safe and do not generate core dumps like callback functions.
All classes derived from qobject or its subclass (such as qwidget) can contain signals and slots. When an object changes its state, the signal is sent out by the object (emit). This is all the things the object has to do. It does not know who is receiving the signal at the other end. This is the true information encapsulation, which ensures that the object is used as a real software component. Slots are used to receive signals, but they are common object member functions. A slot does not know whether any signal is connected to itself. Moreover, the object does not understand the specific communication mechanism.
You can connect many signals to a single slot, or connect a single signal to many slots, or even connect one signal to another, at this time, no matter when the first signal is sent, the system will immediately launch the second signal. In short, signals and slots construct a powerful component programming mechanism.
Signal
When a signal changes the internal status of its customer or owner, the signal is transmitted by an object. Only the class that defines this signal and its derived class can transmit this signal. When a signal is sent, the associated slot is immediately executed, just like a normal function call. The signal-slot mechanism is completely independent of any GUI event loop. The emission function (emit) is returned only after all slots are returned. If multiple slots are associated with a specific signal, these slots will be executed one by one when the signal is sent, however, their execution order will be random and uncertain. We cannot artificially specify the first execution and the second execution.
The signal declaration is carried out in the header file. The signals keyword of QT indicates that it enters the signal declaration area and then declares its own signal. For example, three signals are defined below:
1 signals:
2
3 void mySignal();
4
5 void mySignal(int x);
6
7 void mySignalParam(int x,int y);
In the above definition, signals is the key word of QT, rather than C/C ++. The next line void mysignal () defines the signal mysignal, which carries no parameters; the next line void mysignal (int x) defines the duplicate signal mysignal, but it carries an integer parameter, this is a bit similar to the virtual function in C ++. Formally speaking, the signal declaration is the same as the ordinary C ++ function, but the signal is not defined by the function body. In addition, the return type of the signal is void, do not expect any useful information from the signal.
Signals are automatically generated by MOC, which should not be implemented in the. cpp file.
Slot
A slot is a common C ++ member function that can be called normally. Its unique characteristic is that many signals can be associated with it. This slot is called when the signal associated with it is sent. Slot can have parameters, but slot parameters cannot have default values.
Since the slot is a common member function, like other functions, they also have access permissions. The access permission of the slot determines who can be associated with it. Like common C ++ member functions, slots are also divided into three types: Public slots, private slots, and protected slots.
Public slots: The slots declared in this region means that any object can connect the signal to it. This is very useful for component programming. You can create objects that do not know each other and connect their signals to the slot so that information can be correctly transmitted. Protected slots: The slots declared in this region means that the current class and its subclass can connect signals to it. This applies to those slots, which are part of the class implementation, but their interface interfaces are external-oriented. Private slots: The slots declared in this region means that only the class itself can connect the signal with it. This applies to closely related classes.
The slot can also be declared as a virtual function, which is also very useful.
The slot statement is also carried out in the header file. For example, the following three slots are declared:
1 public slots:
2
3 void mySlot();
4
5 void mySlot(int x);
6
7 void mySignalParam(int x,int y);
Correlation between signals and slots
Call the connect function of the qobject object to associate the signal of an object with the slot function of another object. In this way, when the transmitter emits a signal, the receiver's slot function is called. The function is defined as follows:
bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member ) [static]
This function is used to associate the signal in the transmitter sender object with the member slot function in the receiver. The macro signal () of QT must be used when the signal is specified, and the macro slot () must be used when the slot function is specified (). If the initiator and receiver belong to the same object, the receiver parameter can be omitted in the Connect call.
For example, the following two objects are defined: the label object and the scroll object of the scroll bar, And the valuechanged () signal is associated with the setnum () of the label object, in addition, the signal carries an integer parameter, so that the label always displays the value of the position of the scroll bar.
1 QLabel *label = new QLabel;
2
3 QScrollBar *scroll = new QScrollBar;
4
5 QObject::connect( scroll,SIGNAL(valueChanged(int)),label,SLOT(setNum(int)) );
A signal can even be associated with another signal. See the following example:
1 class MyWidget : public QWidget
2
3 {
4
5 public:
6
7 MyWidget();
8
9 signals:
10
11 void aSignal();
12
13 private:
14
15 QPushButton *aButton;
16
17 };
18
19 MyWidget::MyWidget()
20
21 {
22
23 aButton = new QPushButton( this );
24
25 connect( aButton, SIGNAL(clicked()), SIGNAL(aSignal()) );
26
27 }
In the preceding constructor, a private button abutton is created for mywidget. The clicked () signal generated by the Click Event of the button is associated with another signal asignal. In this way, when the signal clicked () is sent, the signal asignal () is also sent. Of course, you can also associate a click event with a private slot function and then transmit asignal () signals in the slot. This seems redundant.
When there is no need to continue to associate the signal with the slot, we can use the disconnect function to disconnect the connection. It is defined as follows:
1 bool QObject::disconnect ( const QObject * sender, const char * signal,
2
3 const Object * receiver, const char * member ) [static]
This function disconnects the signal in the transmitter from the slot function in the receiver.
The disconnect () function must be used in three cases:
Disconnects any objects associated with an object. This seems a bit incomprehensible. In fact, when we define one or more signals in an object, these signals are associated with the slots in several other objects, if we want to cut off these associations, we can use this method, which is very simple.
Disconnect (myobject, 0, 0, 0)
Or
Myobject-> disconnect ()
Disconnects any association with a specific signal.
Disconnect (myobject, signal (mysignal (), 0, 0)
Or
Myobject-> disconnect (signal (mysignal ()))
Disconnects two objects.
Disconnect (myobject, 0, myreceiver, 0)
Or
Myobject-> disconnect (myreceiver)
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 sender's sender cannot be 0, and the values of the other three parameters can be equal to 0.
Object meta Tool
The meta object compiler MOC (meta object compiler) analyzes class declarations in the C ++ file and generates C ++ code for initializing the meta object, the object contains the names of all signals, slots, and pointers to these functions.
MoC reads the C ++ source file. If a class with a q_object macro sound is found, it generates another c ++ source file, this newly generated file contains the meta object code of this class. For example, suppose we have a head file mysignal. h. This file contains a signal or a slot statement. Before compilation, the MOC tool will automatically generate a file named mysignal Based on the file. MOC. h c ++ source file and submit it to the compiler; similarly, it corresponds to mysignal. the CPP file MOC tool will automatically generate a file named mysignal. MOC. submit the CPP file to the compiler.
The metadata code is required by the signal/slot mechanism. The C ++ source files generated using MOC must be compiled and connected together with the class implementation, or they can be included in the class source files using the # include statement. MoC does not extend the # include or # define macro definition. It simply skips any preprocessing commands encountered.
Program example
A simple sample program is provided here. The program defines three signals and three slot functions, and then associates the signals with the slot, each slot function is a simple dialog box. You can use kdevelop to generate a simple QT application and add the following code to the corresponding program.
The Declaration of the signal and slot functions is generally located in the header file, and the q_object statement must be added at the beginning of the class declaration. This statement is indispensable, it tells the compiler to apply the MOC tool for extension before compilation. 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 ++.
The declaration of signals is similar to the declaration of functions rather than variables. There must be a type on the left and parentheses on the right. If you want to pass parameters to the slot, specify the type of each formal parameter in brackets. Of course, the number of formal parameters can be more than one.
The keyword slots indicates the declaration of the slot that starts later. Here slots also use the plural form.
The slot declaration is the same as that of a common function. It can carry zero or multiple formal parameters. Since the signal declaration is similar to the declaration of common C ++ functions, the signal can also be declared in the form of virtual functions in C ++, that is, the same name but different parameters. For example, the void mysignal () defined for the first time has no parameters, but the second definition has parameters. here we can see that the QT signal mechanism is very flexible.
The connection between the signal and the slot must be specified using the connect function in advance. If you want to disconnect the two, you can use the disconnect function.