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

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

本文关键字:QProcess 进程 QThread 线程 新线程      更新时间:2023-10-16

我有以下代码:

 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;
 }
}

在这个源代码中,我试图在一些进程开始之前打开一个弹出对话框。问题是对话框是不可点击的,但我想在对话框上创建一个按钮来中止正在运行的方法。正如您所看到的,我尝试使用QThread在另一个线程中运行进程,但仍然无法单击对话框。此外,如果我用"application/x-executable"文件打开我的应用程序(GUI),那么在激活上面显示的方法时,对话框内容就会丢失。如何解决这些问题?我哪里错了?问候

void processmethodONE()
{
   QThread* thread = new QThread;
   Prozess.moveToThread(thread);
   Prozess.start(ProcessComand);

在这里,您将QProcess移到了另一个线程。但随后你对它调用了start()。这已经不是线程安全的了。

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

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

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

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

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

虽然我仍然不完全理解您最近更新的代码示例,但我觉得这可能是您的问题:

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

在等待Prozess完成的过程中,无论您在原始代码中真正调用它的地方都是阻塞的。

为每一个使用一个全新的QProcess实例,并将它们的finished()信号连接到一个SLOT,当它们完成时将调用该SLOT。不要手动轮询和阻止它们。这将允许您完全摆脱QThreads。