Correct usage of qpprocess

In the programming process, it is often used to call other programs in the program. This calls for process calls. In QT, the process calls of QProcess are used. It has the characteristics of QT itself, which is very convenient to use, and is different from the interface of C++ itself. Its flow characteristics are as follows:

Feature 1: waitForStarted is required to judge whether the program starts successfully or fails

Feature 2: you need to wait for finished to judge whether the program is finished

This is also a more traditional usage. Of course, if you don't want to judge the end, you can not judge.

In general, the error that is easy to make in use is to directly omit the processing process of feature 1 and carry out feature 2. If it is normal, there is no problem, but if the called program has a problem, it is difficult to find the reason, as follows:

//Usage of qpprocess
void MainWindow::on_pushButton_2_clicked()
{
    qDebug()<<"enter function MainWindow::on_pushButton_2_clicked";
    QProcess myProcess;
    QStringList arguments;
    arguments += "1";
    arguments += "2";
    myProcess.start("./test", arguments);
    myProcess.closeReadChannel(QProcess::StandardOutput);
    myProcess.closeReadChannel(QProcess::StandardError);
    myProcess.closeWriteChannel();

    while(!myProcess.waitForFinished(500))
    {
        qDebug()<<"wait";
        sleep(2);
        QCoreApplication::processEvents(QEventLoop::AllEvents, 2000);
    }
    qDebug()<<"exit function MainWindow::on_pushButton_2_clicked";
}

The above code seems to be OK and can be executed normally. I specially tested an exception, that is, the above code/ The test program does not exist. The execution is as follows:

enter function MainWindow::on_pushButton_2_clicked
wait
wait
wait
wait
wait
wait
wait
wait

I found that the program has entered a dead cycle. You don't know why. Is it a little confused

The reason is that the program fails to start. At this time, the waitForFinished() function will always return false. The official also has the corresponding instructions:

Returns true if the process finished; otherwise returns false (if the operation timed out, if an error occurred, or if this QProcess is already finished)

It's clear that if the process is over, it will always return false, so it enters an endless loop.
Then how to solve it?
Now let's talk about the standard process of qpprocess, as follows:

//Usage of qpprocess
void MainWindow::on_pushButton_2_clicked()
{
    qDebug()<<"enter function MainWindow::on_pushButton_2_clicked";
    QProcess myProcess;
    QStringList arguments;
    arguments += "1";
    arguments += "2";
    myProcess.start("./test", arguments);
    myProcess.closeReadChannel(QProcess::StandardOutput);
    myProcess.closeReadChannel(QProcess::StandardError);
    myProcess.closeWriteChannel();

    if(myProcess.waitForStarted())
    {
        qDebug()<<"Start successful";
    }
    else
    {
        qDebug()<<"Start failed error:"<<myProcess.errorString();
        return;
    }

    while(!myProcess.waitForFinished(500))
    {
        qDebug()<<"wait";
        sleep(2);
        QCoreApplication::processEvents(QEventLoop::AllEvents, 2000);
    }
    qDebug()<<"exit function MainWindow::on_pushButton_2_clicked";
}

After this, the output is as follows:

enter function MainWindow::on_pushButton_2_clicked
 Start failed error: "Process failed to start: The system cannot find the specified file."

In this way, you will know the error and will not enter the dead loop. This also shows that if you want to get the result returned by the program, waitForStarted() and waitForFinished() functions are indispensable.

Keywords: C++ Qt

Added by hightechredneck on Wed, 02 Mar 2022 12:48:40 +0200