3

我正在学习 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()插槽的输出。

现在我的问题是:如何启动上述其他工作并从每个实例接收单独的更新。

4

1 回答 1

5

启动额外的工作和接收更新很容易;您只需多次执行上面发布的代码。

唯一稍微棘手的部分(我认为您问题的核心)是如何判断何时调用 readReadyStandardOutput() (或等)插槽,几个 QProcess 对象中的哪一个是调用它的对象。

有几种方法可以解决这个问题。没有特别的顺序:

  • 您可以为每个 QProcess 对象声明不同的插槽(例如 readReadyStandardOutput1()、readReadyStandardOutput2() 等)并将每个 QProcess 连接到不同的插槽。(除非您只有非常少量的 QProcesses,否则不推荐)

  • 您可以创建一个派生自 QObject 的单独 ProcessLauncher 类,并为您要启动的每个任务创建一个 ProcessLauncher 对象。让每个 ProcessLauncher 对象创建自己的 QProcess 对象并将 QProcess 的信号连接到 ProcessLauncher 的插槽。由于每个 ProcessLauncher 与其 QProcess 之间存在 1:1 的关系,ProcessLauncher 将知道它的插槽是由它自己的 QProcess 调用的,而不是其他的。

  • 您可以使用QSignalMapper对象来帮助您区分信号。

  • 或者,如果您不介意颠覆信号和插槽范式的面向对象性质,您的插槽方法可以调用QObject::sender()来找出发出信号的 QProcess,并改变它们的行为基于 sender() 的返回值。

于 2013-11-02T06:57:07.927 回答