如何在不冻结 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?