Someone wrote a letter last month to ask me this question. At that time, I made a more detailed answer and put the answer content up. Maybe it will be of some use to others. In some cases, my understanding may be incorrect. please correct me:
Problem: The graphic interface of the small software I made is based on qt3.2. after entering the command in the command line edit box on the main interface, I want to execute executable files that have been written by others. The execution of these executable files takes a long time. When running on the terminal, some running information is displayed, and the execution result is displayed. There is a text box on my interface. I want to add the information in the background execution process to the text box, which is equivalent to real-time display, but the requirements are not that high.
Let me explain how I do it now. I defined a command line edit box in a class named qgui_commandwidget (which belongs to the main window) and input a command to define a qtextedit object to display the execution information, A custom mythread class object is defined to execute external programs. In this thread's run function, I call the fork and execv functions to execute external programs, redirects the standard output of the executable program to the pipeline, reads the information from the pipeline, and then transmits the information back to the main thread using the qapplication: postevent () function, the main thread append the information to the text box.
My questions are:
First, can I use the fork and execv functions to execute external programs? Do I have to use qprocess? Why? The Forum is not very clear. How can this problem be solved? Create a qprocess class object in the qgui_commandwidget class or create another qprocess Class Object in my mythread class object?
Second, how should we implement qt3-based communication between GUI threads and non-Gui threads? I cannot change the external program. I don't know when it will end. How can I read the output information of qprocess and display it back in the text box of my main window? How do I know that the executable program ends and then kills the thread?
Third, I saw in "C ++ GUI programming with qt3": "The qtimer class and the qftp, qhttp, qsocket, and qsocketnotifier class applied to the network are all based on message event loops, therefore, it cannot be used in non-Gui threads." Why? In addition, I have read that qsocketnotifier is used in the examples of using qqsocketdevice. In your blog, you can use qthread, qqsocketdevice, and qwaitcondition to collect videos. Do you also use qsocketnotifier?
Answer: 1) fork and execv functions can be fully used. In fact, the qprocess class only encapsulates these underlying functions.
Yes, but considering the use of qprocess, you do not need to process the program pipeline by yourself or yourself.
In Windows, it can save a lot of time. Therefore, we recommend that you use qprocess.
It will be the same.
2) depending on your needs, you can use no threads, because qprocess has handled these tasks by itself.
After the start function of qprocess is used to execute external programs, this function will not be blocked. In addition
Qprocess also automatically returns the information returned by external programs in the form of events. For details, refer to the following
Simple Example:
Class enstcdrecord: Public qobject
...{
............
Qprocess mprocess;
};
Enstcdrecord: enstcdrecord (qwidget * pparent)
...{
Mparent = pparent;
Connect (& mprocess, signal (readyreadstandarderror (), this,
Slot (readprocessoutput (); // connects to the readyreadstandarderror event.
You can obtain information in the stderr program and connect to its readyreadoutput event.
}
Bool enstcdrecord: creatmcm (const qstring & pimagefile)
...{
Qstringlist cmdlist;
Cmdlist. append ("-V ");
Cmdlist. append ("speed = 2 ");
Cmdlist. append (pimagefile );
Mprocess. Start ("cdrecord.exe", cmdlist );
While (! Mprocess. waitforfinished (300)... {// after the program is started, wait until it is completed in a loop.
If you are not concerned about when the program ends, the following code is not required.
If (mprocess. State () = qprocess: notrunning)... {// process failed
Qmessagebox: Critical (mparent, systemname, TR ("error when record CD ."));
Return false;
}
Qapp-> processevents (); // prevents UI deadlocks. This is usually used for a short period of time (
300 ms), so the UI response method is enough.
}
If (mprocess. exitcode ()! = 0)... {// error when run process
Qmessagebox: Critical (mparent, systemname, TR ("error when record CD ."));
Return false;
}
Return true;
}
Void enstcdrecord: readprocessoutput ()
...{
Qmessagebox: Critical (mparent, systemname,
Mprocess. readallstandarderror (); // display the stderr information of the program.
}
Whether the external program uses stdout or stderr as the output of the running state, where
Different processing methods, or even no output, need to be tested by yourself.
3) In general network programs, qsocket and qsocketnotifier can be used in the main thread.
When data is sent and received, they do not cause a deadlock on the program interface. When I write a blog, my
After the program receives data from the network, it needs to do some computing and storage work.
Large, and the program has high performance requirements. Therefore, the entire network data receiving function can only be put into the thread.
In that case, qsocket does not apply, but must use the synchronized qsocketdevice.
In fact, qt3 provides two network access functions: qftp, qhttp, qsocket, and
Qsocketnotifier and so on, all of which are notified by event after receiving data. Another type is
Qsocketdevice, which does not send any notification event, but must be queried by an external program, or
Only when the user receives the data can they know when the data is received.
The sentence in "C ++ GUI programming with qt3" is correct (but it is for qt3,
In qt4, there are no such classes at the root, and threads in qt4 can also use events ). In qt3,
Only the UI thread can use events, which cannot be used in other auxiliary threads. Therefore
The categories of events for notification.
Qsocketnotifier is not used in my program. As mentioned above, this class is only used with qsocket
Yes. It is notified of test events. My program uses qsocketdevice and relies on its wait
Function to wait for the data to arrive.