如何在不冻结 gui 的情况下运行 QProcess 的同步链?

Posted

技术标签:

【中文标题】如何在不冻结 gui 的情况下运行 QProcess 的同步链?【英文标题】:How to run a synchronous chain of QProcess without freezing the gui? 【发布时间】:2012-06-25 15:10:19 【问题描述】:

我想借助一些外部程序来优化图像。程序必须一个接一个地执行,其中一些取决于最后一个程序的输出,其中一些取决于图像的特性。

我知道,我可以使用信号,但这在这里不是很有用,因为我必须为每个外部程序使用几十个函数和信号,其中一些甚至多次取决于位置,其中一个程序在链中被调用。一个一个地执行它们会容易得多。但是,如果我这样做,即使在所有进程完成之前不显示状态消息,gui 也会立即冻结。我还能做什么?

ui->status->setText("Do something with program 1");

QProcess *proc1 = new QProcess;
proc1->setReadChannelMode(QProcess::SeparateChannels);
proc1->start("program 1 -args", QIODevice::ReadWrite);

while(!proc1->waitForFinished(10))
    ;

ui->status->setText("Do something with program 2");

QProcess *proc2 = new QProcess;
proc2->setReadChannelMode(QProcess::SeparateChannels);
proc2->start("program 2 -args", QIODevice::ReadWrite);

while(!proc2->waitForFinished(10))
    ;

【问题讨论】:

线程可以。顺便说一句,您可以创建一个插槽,比如说“on_qprocess_done”,准备命令列表(或动态生成它们)并使用它来代替普通的阻塞线性算法。 【参考方案1】:

在这种情况下,使用信号是“正确”的方式。你只需要链接它们。

[...]
ui->status->setText("Do something with program 1");
proc1.setReadChannelMode(QProcess::SeparateChannels);
proc1.start("program 1 -args", QIODevice::ReadWrite);
connect(proc1, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finishedProc1()))
[...]

void finishedProc1()

   ui->status->setText("Do something with program 2");
   proc2.setReadChannelMode(QProcess::SeparateChannels);
   proc2.start("program 2 -args", QIODevice::ReadWrite);
   connect(proc2, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finishedProc2()))


void finishedProc2()

  [...]

或者,您可以在等待时在 QApplication 中调用 processEvents,或者在不同的 QThread 中执行整个操作。

【讨论】:

致电QCoreApplication::processEvents(); 拯救了我的一天。谢谢!【参考方案2】:

创建工作线程(多个线程,如果您需要并行处理)并在那里等待。 GUI 将不会被阻止。

【讨论】:

以上是关于如何在不冻结 gui 的情况下运行 QProcess 的同步链?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不冻结 GUI 的情况下让 AudioQueue 播放?

如何在不冻结 GUI 的情况下使用视频帧不断更新 contentcontrol?

如何在不冻结 GUI 的情况下在单个插槽中实现阻塞进程?

PyQt5 在不冻结 GUI 的情况下绘制数据的最佳方法 [关闭]

QT - 在不阻止他的 GUI 的情况下显示小部件

如何在不关闭 GUI 窗口的情况下停止运行 PyQt5 程序?