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;
*/
出力はまったく同じです!印刷後しばらくの間だけ残る
スレッドはまだ実行中ですか?!!!!
誰かがこれで私を助けてくれますか? どうもありがとう。すべてのコードをコピーして、自分でテストするだけです。
-------------------------元の質問、悪い説明、無視してください------------------------ ---------------------------
フレームをクエリする関数が 1 つだけの 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() は true です。
ただし、次のようなことをすると:
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()について私を混乱させます...ありがとう!