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

Sou*_*abh 2 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();
Run Code Online (Sandbox Code Playgroud)


每件事情都很好,但是当流程运行时,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;
}
Run Code Online (Sandbox Code Playgroud)


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

bcm*_*inc 5

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

如果您希望您的进程在函数返回后继续运行.必须使用new以下方法在堆上创建它们:

QProcess * ffmpeg = new QProcess(this);
QProcess * x265 = new QProcess(this);
Run Code Online (Sandbox Code Playgroud)

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

connect(ffmpeg, SIGNAL(finished(int,QProcess::ExitStatus)), ffmpeg, SLOT(deleteLater()));
connect(x265, SIGNAL(finished(int,QProcess::ExitStatus)), x265, SLOT(deleteLater()));
Run Code Online (Sandbox Code Playgroud)

  • 这有助于:`ffmpeg-> close();`和`x265-> close();`也可以杀死进程:参见[QProcess :: close]的文档(http://qt-project.org/doc/ QT-4.8/qprocess.html#接近). (2认同)