如何在新线程(QThread)中使用进程(QProcess)?

Str*_*ght 4 c++ qt qprocess qdialog qthread

我有以下代码:

 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;
 }
}
Run Code Online (Sandbox Code Playgroud)

在此源代码中,我尝试在某些进程启动之前打开一个弹出对话框。问题是对话框不可点击,但在对话框上我想创建一个按钮来中止正在运行的方法。如您所见,我尝试使用 QThread 在另一个线程中运行进程,但仍然无法单击该对话框。此外,如果我使用“application/x-executable”文件打开我的应用程序(GUI),则在激活上述方法时会丢失对话框内容。我该如何解决这些问题?我哪里错了?你好

Fra*_*eld 5

void processmethodONE()
{
   QThread* thread = new QThread;
   Prozess.moveToThread(thread);
   Prozess.start(ProcessComand);
Run Code Online (Sandbox Code Playgroud)

在这里,您将 QProcess 移动到另一个线程。但是然后你调用 start() 就可以了。那已经不是线程安全的了。

while(!Prozess.waitForFinished(2000))
{
   std::cerr << "Process running " << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这会阻塞并使使用线程无用。此外,它不是线程安全的。

您不应该使用线程,而是:

  1. 删除 waitForFinished() 调用
  2. 将QProcess 的finished() 和error() 信号连接到插槽,然后开始下一步,即processMethodTWO。

我还建议不要重用 QProcess 对象,只需为每个步骤创建一个新对象。