How to use a process (QProcess) in a new thread (QThread)?

Streight picture Streight · Mar 25, 2012 · Viewed 10.9k times · Source

I have the following code:

 void Processmethod()
{

    QDialog *ProcessMessage = new QDialog;      
    Ui::DialogProcessMessage Dialog;            
    Dialog.setupUi(ProcessMessage);             
    ProcessMessage->setModal(true);
    ProcessMessage->setAttribute(Qt::WA_DeleteOnClose); 
    ProcessMessage->show();

    qApp->processEvents();

    processmethodONE();  
    processmethodTWO();
    processmethodTHREE();                  
}

void processmethodONE()
{
    QString ProcessCommand = "w8 " + blablubli";            

    Prozess.setWorkingDirectory(Path);         //QProcess "Prozess" is globaly defined  
    Prozess.setStandardOutputFile(Path);       //in my class

    QThread* thread = new QThread;
    Prozess.moveToThread(thread);
    Prozess.start(ProcessCommand);


while(!Prozess.waitForFinished(2000))
   {
       std::cerr << "Process running " << std::endl;
   }

QProcess::ExitStatus Status = Prozess.exitStatus(); 

if (Status == 0)
 {
   std::cout << "File created!" << std::endl;
 }
}

In this source code I try to open a popup dialog before some processes are starting. problem is that the dialog is not clickable, but on the dialog I want to create a button to abort the running method. As you can see I tried using QThread to run the process(es) in another thread, but still I can't click the dialog. Furthermore if I open my application (GUI) with the "application/x-executable"-file the dialogs content is missing when activating the above shown method. How can I fix these problems? Where am I wrong? greetings

Answer

Frank Osterfeld picture Frank Osterfeld · Mar 25, 2012
void processmethodONE()
{
   QThread* thread = new QThread;
   Prozess.moveToThread(thread);
   Prozess.start(ProcessComand);

Here you moved the QProcess to another thread. But then you call start() on it. That's already not thread-safe.

while(!Prozess.waitForFinished(2000))
{
   std::cerr << "Process running " << std::endl;
}

This blocks and makes using a thread useless. Also, it's not thread-safe.

You should instead not use threads but:

  1. remove the waitForFinished() call
  2. Connect the finished() and error() signals of the QProcess to slots which then start the next step, i.e. processMethodTWO.

I would also advise against reusing QProcess objects and just create a new one for each step.