我需要做什么
我正在构建一个运行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不会冻结。请帮助。
答案 0 :(得分:5)
您正在堆栈上创建QProcess
es。这意味着当函数返回时,ffmpeg
和x265
对象将被销毁。这也会杀死这些过程。
如果您希望您的进程在函数返回后继续运行。必须使用new
:
QProcess * ffmpeg = new QProcess(this);
QProcess * x265 = new QProcess(this);
现在你还需要自己破坏ffmpeg
和x265
个对象,否则你会泄漏内存。以下内容将等到进程完成后才能清除对象。
connect(ffmpeg, SIGNAL(finished(int,QProcess::ExitStatus)), ffmpeg, SLOT(deleteLater()));
connect(x265, SIGNAL(finished(int,QProcess::ExitStatus)), x265, SLOT(deleteLater()));