Application Development in Linux: Internal Process Communication of QT
Http://www.lupaworld.com/tutorial-view-aid-7177.html
As a cross-platform C ++-based GUI system, QT provides powerful functions for users to construct graphical user interfaces. Since the release of QT in 1996 by trolltech, the system has become the main system used by many successful graphic user applications in the world. More importantly, the Linux operating system's desktop environment system KDE is also constructed based on QT. Currently, QT has provided support for MS/Windows, UNIX/X11 and embedded platform, and has been more and more widely used.
In the QT system, not only has a well-structured system structure, but also creates many new system mechanisms to meet users' requirements for compiling graphic user interface applications, the internal process communication mechanism specific to QT is particularly worth mentioning. This article analyzes three common communication mechanisms based on QT: qcop protocol, signal-Slot Mechanism and FIFO mechanism. Their respective usage methods are provided, and their respective application scenarios are pointed out.
1. qcop Protocol
Qcop is a communication protocol within QT, which is used for communication between different customers within the same address space or between different processes. Currently, this mechanism is only available in the embedded version of QT.
To implement this communication mechanism, QT includes the qcopchannel class inherited from the qobject class, which provides static functions such as send () and isregistered, they can be used without objects. To receive communication data in a channel, you need to construct a sub-class of qcopchannel and provide an overload function of the receive () function, or use the connect () function to associate with the received signal.
It is worth mentioning that in the QT system, only the qcop Protocol mechanism and the class for receiving messages are provided, and the corresponding class is not provided for users to send messages.
In the QT-based desktop system qtopia (qpe), qcopenvelope is provided. You can use this channel to send messages to other processes. This class encapsulates the process of sending a qcop message through qcopchannel. You only need to call the relevant functions in this class to conveniently implement the communication process between processes. On the one hand, the qcopenvelope class is used for sending a qcop message, and on the other hand, the message is received by associating with a qcopchannel.
When sending a message, the following protocol mechanism is used:
Qcopenvelope E (channelname, messagename );
For messages that require parameters, you must use the <() "operator to add the parameters to envelope.
E <parameter1 <parameter2 <...;
For messages without parameters, you only need to use:
Qcopenvelope E (channelname, messagename );
In qtopia, all channels names start with "qpe/", while messagename is the identifier of a function.
When receiving a message, you usually only need to use the pre-defined qpe/application/{appname} pipeline in the application. Of course, you can also define the pipeline as needed, and associate it with a slot function:
Mychannel = new qcopchannel ("qpe/foobar", this );
Connect (mychannel, signal (received (const qcstring &, const qbytearray &)),
This, slot (foobarmessage (const qcstring &, const qbytearray &)));
The following is an example of a specific communication process:
Define the pipeline in the class (such as window1) for receiving messages:
Qcopchannel * dochannel = new qcopchannel ("qpe/do", this );
Connect (dochannel, signal (received (const qcstring &, const qbytearray &), this, slot (domessage (const qcstring &, const qbytearray &)));
In addition, you need to define the corresponding message processing function domessage in this class,
Void window1: domessage (const qcstring & MSG, const qbytearray & ARGs)
{
Qdatastream stream (ARGs, io_readonly );
If (MSG = "message1 (qstring )")
{
Qstring text;
Stream> text;
Button-> settext (text );
}
Else if (MSG = "message2 ()")
{
Close ();
}
}
Message1 (qstring) and message2 (qstring) are user-defined messages. These messages are processed in this function. In this example, when the message1 message with the parameter is received, the stream string parameter is displayed on the button. When the message2 message is received, the window1 window is closed, of course, you can write the corresponding processing process as needed.
On the other hand, qcopenvelope is used to send messages in functions that need to send messages in class2:
Void class2: function ()
{Qcopenvelope E ("qpe/do", "message1 (qstring )");
E <Param ;}
Here the message1 message is sent and the parameter Param to be carried is sent to the MPs queue.
Through this process, you can easily implement the communication process between different objects and processes, and you can transmit any parameters during the communication process as needed.
2. Signal-Slot Mechanism
In QT, there is a signal-slot mechanism used for communication between objects. This mechanism is the core mechanism of QT and is also the main feature that distinguishes it from other GUI tools. In most GUI tools, a callback function is usually defined for each behavior that may be triggered. This callback function is a pointer to the function. In QT, the signal-Slot Mechanism replaces this complicated function pointer to implement the same function. The signal-slot mechanism can carry any type and number of parameters, and is completely secure without causing system crashes.
All classes inherited from the qobject class, or a subclass of it, can contain the signal-slot mechanism. Signals are usually sent when objects change their state. This is what an object needs to do when it needs to communicate with other objects, it does not know whether other objects receive the signal at the other end. In this sense, this mechanism achieves true information encapsulation, ensuring that the object can be used as an independent software component.
The slot can be used to receive signals, which are usually member functions in the class. A slot does not know whether a signal is associated with itself. Similarly, objects containing slot functions do not know the communication mechanism. They can also be used as independent software components.
You can associate many signals with a single slot function as needed. A single signal can also be associated with many different slot functions as needed. You can even associate a signal directly with another signal, so that the second signal is sent immediately when the first signal is sent.
In this way, the combination of signals and slots produces a powerful programming mechanism.
For example:
Button = new qaction (TR ("button"), qiconset (qpixmap ("button.png"), 0, 0, this );
Connect (button, signal (activated (), this, slot (slotbutton ()));
The program defines a button and uses the connect () function to associate the activated () signal of the button with the slotbutton () function. When a user triggers the button, the corresponding slot function is executed. Of course, the signal here is a pre-defined signal in the qaction class. When using this mechanism, you can define the signal as needed and use the emit statement to send the signal as appropriate. In addition, any parameters can be transmitted between the signal and the corresponding slot function, such:
Emit signal (parameter );
3. FIFO Mechanism
Of course, apart from the internal communication mechanism specific to QT, common inter-process communication mechanisms in operating systems can also be used for communication between different processes in QT systems. Such as message queue, shared memory, semaphores, pipelines, and other mechanisms, some of which, such as semaphores, are re-encapsulated in QT; some mechanisms can be implemented by directly calling the operating system. The famous pipeline is a simple and practical communication mechanism.
If you do not know much about it, you can also use this method to implement communication between object processes. The following describes how to use this mechanism to implement communication between internal processes of QT.
First, you need to create a FIFO. This process is similar to creating a file. In the system, you can use the mkfifo command to create a file. In this way, you can use the open function to open it, general file I/O functions (close, read, write) can be used for FIFO.
In QT-based applications, many applications adopt a client-server mode. In this case, FIFO can be used to transmit data between the client and the server. For example, a server is responsible for receiving messages from the underlying program. At the same time, it is related to many clients. The server needs to send different messages to different clients, each client also needs to send requests to the server and then to the underlying program.
The following is an example of a server program: (set up an existing client process to open/dev/javasoclient1 and/dev/javasoclient1 for read purposes)
FD = open ("/dev/fifoserver", o_nonblock | o_rdonly );
File = fdopen (FD, "R ");
Ret = fgets (BUF, max_line, file );
If (BUF [0] = '0 ')
{
Qfile fd_file ("/dev/kerberoclient1 ");
Qstring temp (BUF );
If (fd_file.open (io_writeonly | io_append )){
Qtextstream T (& fd_file );
T <temp;
Fd_file.close ();
}
Else if (BUF [0] = '1 ')
{
Qfile fd_file ("/dev/kerberoclient2 ");
Qstring temp (BUF );
If (fd_file.open (io_writeonly | io_append )){
Qtextstream T (& fd_file );
T <temp;
Fd_file.close ();
}
......
In this program, the server receives the information sent from the underlying layer (which is assumed to be sent from the FIFO channel), and then according to the received information, such as the content of the first byte, send the information to the pipelines of different clients to distribute the information correctly.
The client program example is as follows: (assume that the/dev/FIFO pipeline has been opened on the server for reading)
Qfile out_file ("/dev/FIFO ");
If (out_file.open (io_writeonly | io_append )){
Qtextstream T (& out_file );
T <text <"/N ";}
When any client needs to send messages to the server, it can be sent through the public pipeline/dev/FIFO.
This method can also implement the communication process between different processes or applications in the GUI. However, when there are a large number of clients, this method shows some limitations, the entire communication process has become too complex, and pipelines are increasingly prone to errors. Therefore, the use of FIFO to implement communications between the client and the server in QT is more suitable for clients with fewer applications.