QProcess, QEventLoop and Bourne Shell
-
Hi, I have the source code:
@void MyClass::CreateFile()
{
std::cout << "Process running!" << std::endl;QString Command = "m4 " + "/x/y/z"; // 1. Prozess.setWorkingDirectory(Path); // Prozess is a global QProcess object Prozess.setStandardOutputFile(Path + "/TheFile"); QEventLoop loop; connect(&Prozess, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit())); connect(&Prozess, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit())); Prozess.start(Command); loop.exec(); //2. //Start of local event loop???
.
.
.
}@Regarding this part of source code I have some questions:
-
The command in the line marked with //1. originally was used in a .sh file (Bourne Shell File). I`ve read that the Bourne Shell usually first interprets command lines before executing them/passing them to the operating system. So I have to ask myself if it is save to use the originally .sh file commands the way described in the source code above? In other parts of my source code I used even more commands (other commands) of this .sh file the same way, but when now reading about the Bourne Shell I am not sure if what I am doing is generally safe, since the way I use the command I guess it is directly send to the operating system, right?
I know that in this command line the m4 macro-processor is used on the file "z" located in "/x/y/z". -
Marked with //2. in the above source code: What does "loop.exec();" exactly in the above case mean? I've already read QEventLoop Class Description, but I don't get it. Do I run here the QProcess "Prozess" in the LocalEventLoop "loop" and when "Prozess" is finished or an error occured, hence "quit()" is called, the "loop" is left? If that is right I am also a little confused about the fact that the LocalEventLoop "loop" is started after the QProcess "Prozess" has started....
Hope someone can tell me what exactly is going on here since I am not sure - couldn't even find a german word for "exec".
greetings
-
-
Regarding question 1:
QProcess does some command line parsing too. To cite the documentation:bq. Starts the program program in a new process, if one is not already running. program is a single string of text containing both the program name and its arguments. The arguments are separated by one or more spaces
So, the executable m4 is started and /x/y/z is passed to it as argument.
Another option is to put the arguments explicitly into a QStringList and pass that one as additional argument to start().
But be aware, that QProcess' parsing does not do variable expansion (such as $HOME) and expansion of file globbing (like in 'ls *.cpp')
Regarding question 2:
The event loop blocks until the process has finished. The call to exec of that event loop blocks, i.e. exec() only returns after the loop has finished. As this would only happen after the process has finished (the connect statements), it would run forever, as the process has no chance to start :-)The local event loop is a commonly used pattern to block at a certain point while keeping an event loop running. In the special case of QProcess, it's not necessary, though. I'd suggest to call "QProcess::waitForFinished() ":/doc/qt-4.8/qprocess.html#waitForFinished here.
-
Hi again,
one more question:
In which line do I exactly define, that the QProcess “Prozess” runs ins the LocalEventLoop “loop” ?
Is the LocalEventLoop “loop” already started with@ QEventLoop loop;@
?
greetings
-
The loop is created with that line, it is started with the call to exec():
@
loop.exec(); // starts the event loop
@But as I stated earlier, I would use waitForFinished():
@
void MyClass::CreateFile()
{
std::cout << "Process running!" << std::endl;QString Command = "m4 " + "/x/y/z"; Prozess.setWorkingDirectory(Path); Prozess.setStandardOutputFile(Path + "/TheFile"); Prozess.start(Command); Prozess.waitForFinished();
}
@That does the same (block your method until the process has finished) without the need of a local event loop.
-
Allright, thx for the help. When I started programming my GUI I started using "Prozess.waitForFinished()", but there where some problems with running the process, for example the following source code was executed while the process was not finished. Since I am now finished and the source code has changed a lot I could try it again. But, because I have no more time and the local loops work really fine I will leave it as it is.