c++ - 使用 waitForFinished 时 Qt GUI 卡住..替代方案?

标签 c++ qt qprocess

我需要做什么
我正在构建一个 qt 应用程序,它运行一个 exe 并将其输出通过管道传输到其他 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 不会卡住。请帮忙。

最佳答案

您正在堆栈上创建QProcess。这意味着当您的函数返回时,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()));

关于c++ - 使用 waitForFinished 时 Qt GUI 卡住..替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25338729/

相关文章:

c++ - 在使用 Qt 制作的 GUI 上按下按钮时启动 shell 脚本

c++ - VS2012 调试中 SFML 变量周围的损坏堆栈

c++ - Allegro 5 al_create_display(x, y) 不工作

c++ - 将可变函数参数转发到 std::function 对象

QThread 和 C++11 lambda : wait for finished

c++ - 使用 QThread 显示构建问题的时间延迟

python - QProcess 未调用完成?

c++ - 向状态栏添加图标 - Qt

c++ - 获取组中选中单选按钮的索引

python - 向 Python QProcess 示例添加按钮和单独的窗口