我一直在努力解决这个基本问题。
我正试图从一个帖子开始QProcess
。启动过程工作正常,过程运行正常但我的问题是finished()
信号永远不会发出。
以下是我的例子:
我的班级变量是
std::atomic<bool> recording;
QProcess proc;
std::unique_ptr<std::thread> recordingThread;
班级:
Recorder::Recorder(ParentClass *parent): QObject(parent){
connect(&proc,SIGNAL(finished(int)),this,SLOT(finishedFFMPEG()));
}
void Recorder::start(){
if (!recordingThread){
recording = true;
recordingThread.reset(new std::thread(&Recorder::recordThread, this));
}
}
void Recorder::recordThread(){
while(recording){
//writing frame
}
proc.start("C:\\ffmpeg.exe", QStringList() <<"-i"<< picDir.c_str() << "-r"<< "30" << "-vcodec"<< "ffv1" << filename.c_str());
proc.waitForStarted();
}
void Recorder::stop(){
if (recordingThread) {
recording = false;
recordingThread->join(); recordingThread.reset();
}
}
void Recorder::finishedFFMPEG(){
qDebug() << "finished";
}
start()
和stop()
是从ParentClass
中的另一个非GUI线程调用的。
我尝试了一切使用指针,将recordThread()
作为QThread
运行并在QProcess
函数中启动stop()
,但我根本就没有收到finished()
来自过程的信号。进程本身正在正确执行。我知道问题在于不同的事件循环。
如何在recordThread()
完成并抓住QProcess
finished()
信号后实现启动流程的目标?
答案 0 :(得分:3)
我不能说我对你的构造不起作用感到非常惊讶。在另一个线程中使用std :: thread执行成员函数recordThread()。到现在为止还挺好。在recordThread()中,你有一个循环,它看起来像是收集/创建/写入帧。一旦循环离开,帧就会通过QProcess传递给ffmpeg。至少这是你的意图。我做对了吗?
现在,在stop()中清除记录标志,这会导致while循环结束。 QProcess开始。但同时你结束了这个QProcess所在的recordThread()线程。并且您期望不仅QProcess能够存活,它可能会存在,而且所有信号/插槽连接都保持不变?
我并不完全知道QProcess会发生什么,可能的比赛,阻塞/非阻挡效果,但我敢打赌你的问题恰好就在这个区域。
还有一件事......我不认为在线程A中创建QProcess是健康的,但是就像你一样在线程B中启动它。
我会尝试这样的事情(未经测试):
while(recording){
//writing frame
}
QProcess p;
connect(&p,SIGNAL(finished(int)),this,SLOT(finishedFFMPEG()));
p.start(...your ffmpeg stuff...);
p.waitForFinished(-1);
并在finishedFFMPEG()
中recordingThread->join(); recordingThread.reset();
当QProcess完成时,线程被杀死。