我需要做什么
我正在构建一个 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
。这意味着当您的函数返回时,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()));
关于c++ - 使用 waitForFinished 时 Qt GUI 卡住..替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25338729/