我正在学习Qt并且可以使用教程中的以下代码来启动外部应用程序并从中接收处理输出:
void Dialog::on_startButton_clicked()
{
QString program = "C:/Program Files/ffmpeg/bin/ffmpeg.exe";
mTranscodingProcess = new QProcess(this);
connect(mTranscodingProcess, SIGNAL(started()), this, SLOT(processStarted()));
connect(mTranscodingProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(readyReadStandardOutput()));
connect(mTranscodingProcess, SIGNAL(finished(int)), this, SLOT(encodingFinished()));
QStringList arguments;
QString input = "myfile_path_1";
QString input2 = "myfile_path_2";
arguments << "-y" << "-i" << input << "-i" << input2 << "-c" << "copy" << "output.avi" ;
qDebug() << arguments;
mTranscodingProcess->setProcessChannelMode(QProcess::MergedChannels);
mTranscodingProcess->start(program, arguments);
}
这可以按预期工作,我可以捕获和处理应用中readyReadStandardOutput()
和encodingFinished()
个插槽的输出。
现在我的问题是:如何启动上述其他作业并从每个实例接收单独的更新。
答案 0 :(得分:4)
启动其他作业并接收更新非常简单;你只需执行多次上面发布的代码。
唯一有点棘手的部分(我认为你的问题的核心)是如何判断,当调用readReadyStandardOutput()(或者等)槽时,几个QProcess对象中的哪一个是调用它的那个。 / p>
有几种方法可以解决这个问题。没有特别的顺序:
您可以为每个QProcess对象声明不同的插槽(例如readReadyStandardOutput1(),readReadyStandardOutput2()等),并将每个QProcess连接到不同的插槽。 (除非你只有极少数的QProcesses,否则不推荐使用)
您可以创建一个从QObject派生的单独ProcessLauncher类,并为要启动的每个任务创建一个ProcessLauncher对象。让每个ProcessLauncher对象创建自己的QProcess对象,并将QProcess的信号连接到ProcessLauncher的插槽。由于每个ProcessLauncher与其QProcess之间存在1:1的关系,因此ProcessLauncher会知道其插槽由其自己的QProcess调用而不是其他。
您可以使用QSignalMapper对象来帮助您区分彼此的信号。
或者,如果您不介意颠覆信号和插槽范例的面向对象特性,您的插槽方法可以调用QObject::sender()来找出发出信号的QProcess。 ,并根据sender()的返回值改变他们的行为。