我是 Qt 新手,只想在 Qt GUI 中显示视频。除了处理 QThread 的一些细节,我基本上都弄清楚了,这真的很烦人。
我将我的问题重新表述为一个更简单的程序,希望它能更好地解释
首先我定义了这个 QObject 类
#include <QObject>
#include <QDebug>
class myObject : public QObject
{
Q_OBJECT
public:
explicit myObject(QObject *parent = 0);
bool stop;
signals:
void finishWork();
public slots:
void dowork();
void onfinishThread();
};
myObject::myObject(QObject *parent) :
QObject(parent)
{
stop = true;
}
void myObject::dowork(){
qDebug()<<"start working!";
while(!stop){
qDebug()<<"working...";
}
emit finishWork();
qDebug()<<"finish do work!";
}
void myObject::onfinishThread(){
qDebug()<<"thread is finished!";
}
然后是主要功能
#include <QCoreApplication>
#include <QThread>
#include <iostream>
#include <windows.h>
#include "myobject.h"
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
myObject* myObj = new myObject();
QThread* myThread = new QThread;
myThread->connect(myObj, SIGNAL(finishWork()), SLOT(quit()));
myObj->connect(myThread, SIGNAL(started()), SLOT(dowork()));
myObj->connect(myThread, SIGNAL(finished()), SLOT(onfinishThread()));
myObj->moveToThread(myThread);
myObj->stop = false;
myThread->start();
cout<<"Press ENTER to continue....."<<endl<<endl;
cin.ignore(1);
myObj->stop = true;
Sleep(10);
if(myThread->isRunning()){
qDebug()<<"The thread is still running?!!!";
}
/*
myObj->stop = false;
Sleep(1000);
myThread->start();
myObj->stop = true;
*/
myObj->deleteLater();
myThread->deleteLater();
return a.exec();
}
如您所见,我什至使用 cin 尝试让dowork()先运行,但它根本不起作用,输出为
所以我真的很困惑 QThread 的调度是如何工作的......
此外,如果您取消注释该部分
/*
myObj->stop = false;
Sleep(1000);
myThread->start();
myObj->stop = true;
*/
输出完全一样!打印后只停留一段时间
线程还在运行?!!!
有人会帮我吗?非常感谢。您可以简单地复制所有代码并自己测试。
-------------原始问题,不好的解释,请忽略.....------------ --------------------------
我制作了一个只有一个函数来查询帧的 videoObj 类,函数定义为:
void videoObj::ProcessFrame(){
bool getframe;
qDebug()<<"get in ProcessFrame";
while(!stop_flag){
getframe = capture_.read(imgOriginal_);
if(!getframe){
qDebug()<<"Video End!";
break;
}
cv::cvtColor(imgOriginal_, imgOriginal_, CV_BGR2RGB);
QImage qimgOriginal((uchar*)imgOriginal_.data, imgOriginal_.cols, imgOriginal_.rows, imgOriginal_.step, QImage::Format_RGB888);
emit imgProcessed(qimgOriginal);
this->thread()->msleep(10);
//qDebug()<<"processing frames";
}
emit stopProcess();
qDebug()<<"Stop thread";
}
基本上上面的代码只是查询帧,每当有一个发出
SIGNAL imgProcessed(qimgOriginal)
并且每当设置了 stop_flag 时,停止 while 循环并发出
SIGNAL stopProcess()
我在 MainWindow 类中使用这个类,这是我在构造函数中定义连接的方式:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
video_obj_ = new videoObj();
video_thread_ = new QThread;
this->connect(video_obj_, SIGNAL(imgProcessed(QImage)), SLOT(onImgProcssed(QImage))); \\this is for displaying the image
video_obj_->connect(video_thread_, SIGNAL(started()), SLOT(ProcessFrame()));
video_obj_->moveToThread(video_thread_);
video_thread_->connect(video_obj_, SIGNAL(stopProcess()), SLOT(quit()));
}
上面的代码在框架查询中工作正常。我不明白的问题是,如果我在任何 MainWiow 成员函数中设置 video_obj_->stop_flag,videoObj 类中的 ProcessFrame() 应该发出 stopProcess() 信号并触发 video_thread_ 的 quit(),然后线程应该完成,即 video_thread_->finished() 为真。
但是,如果我这样做:
connect(video_thread_, SIGNAL(finished()), this, SLOT(onStopProcess())); //onStopProcess() see below
void MainWindow::on_btnStart_clicked()
{
video_obj_->stop_flag = 1;
this->thread()->msleep(10);
video_obj_->capture_.open(ui->lineEditVidoeAddress->text().toStdString());
//... something about videoCapture setting here, not related
video_obj_->capture_.set(CV_CAP_PROP_POS_FRAMES, 0);
video_obj_->stop_flag = 0;
this->thread()->msleep(10);
if(video_thread_->isRunning()){
qDebug()<<"The thread is still running?!!!";
}
video_thread_->start();
}
void MainWindow::onStopProcess(){
qDebug()<<"thread is finished";
}
它会给我输出:
Stop thread
The thread is still running?!!!
thread is finished
这意味着触发quit() 不是完成线程,或者quit() 没有被触发。
如果我使用:
video_thread_->wait(); //instead of video_thread_->wait(10);
该程序将冻结。
有谁可以帮我解决这个问题,这让我对这个 quit() 和 finished() 感到很困惑......谢谢!