Qt GUI在使用waitForFinished时冻结。替代方案?

时间:2014-08-16 09:21:33

标签: c++ qt qprocess

我需要做什么
我正在构建一个运行exe的qt应用程序并将其输出传递给其他exe。 (在我的情况下ffmpeg | x265
我做了什么

QProcess ffmpeg;
QProcess x265;
ffmpeg.setStandardOutputProcess(&x265);
x265.setProcessChannelMode(QProcess::ForwardedChannels);
ffmpeg.start(ffmpegArgs);
x265.start(x265Args);
if(!ffmpeg.waitForStarted())
 return;
bool retval = false;
while ((retval = x265.waitForFinished(-1)))
{}
ffmpeg.close();
x265.close();


每件事情都很好,但是当流程运行时,GUI会冻结 我试图解决问题

void Basic::on_btnEncode_clicked()
{
    if(fileContainer -> getQueue() -> rowCount() == 0) {
        QMessageBox msg;
        msg.setText("No Input to Convert");
        msg.setIcon(QMessageBox::Information);
        msg.exec();
    }
    QString file;
    int bitRate;
    QString preset;
    QString ffmpegArgs;
    QString x265Args;
    bitRate = ui->sldBitRate->value();
    preset = mapPreset(ui->sldPreset->value());
    for(int i = 0; i < fileContainer->getQueue()->rowCount(); ++i)
    {
        file = QString("\"") +  fileContainer->getQueue()->item(i, 0)->text() + QString("\"");
        ffmpegArgs = Addons::FFmpegExe() + " -i " + file + " -pix_fmt yuv420p -f yuv4mpegpipe -";
        x265Args =  Addons::x265Exe() + " --input - --y4m --preset " + preset + " --bitrate " + QString::number(bitRate) + " --output " + QString("\"") + ui->txtDest->text() + "/out.hevc\"";
        QProcess *ffmpeg = new QProcess(this);
        QProcess *x265 = new QProcess(this);
        ffmpeg->setStandardOutputProcess(x265);
        x265->setProcessChannelMode(QProcess::ForwardedChannels);
        connect(x265, SIGNAL(started()), this, SLOT(processStart()));
        connect(ffmpeg, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(deleteLater()));
        connect(x265, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinish(int,QProcess::ExitStatus)));
        ffmpeg->start(ffmpegArgs);
        x265->start(x265Args);
        ffmpeg->close();
        x265->close();
    }
}


void Basic::processStart()
{
    qDebug() << "started";
}

void Basic::processFinish(int exitcode, QProcess::ExitStatus staus)
{
    qDebug() << "exitcode" << exitcode << "status" << staus;
}


但我总是得到exitcode 62097 status 1的输出,没有任何反应 我该怎么做才能运行该过程,以便GUI不会冻结。请帮助。

1 个答案:

答案 0 :(得分:5)

您正在堆栈上创建QProcess es。这意味着当函数返回时,ffmpegx265对象将被销毁。这也会杀死这些过程。

如果您希望您的进程在函数返回后继续运行。必须使用new

在堆上创建它们
QProcess * ffmpeg = new QProcess(this);
QProcess * x265 = new QProcess(this);

现在你还需要自己破坏ffmpegx265个对象,否则你会泄漏内存。以下内容将等到进程完成后才能清除对象。

connect(ffmpeg, SIGNAL(finished(int,QProcess::ExitStatus)), ffmpeg, SLOT(deleteLater()));
connect(x265, SIGNAL(finished(int,QProcess::ExitStatus)), x265, SLOT(deleteLater()));