本来这篇应该在周四晚上发的,无奈总有各种事情耽搁,下周考虑一下要不要也搞个番茄钟试试 高铁回家开始……
Buttton写到上一篇,有点黔驴技穷,希望广大同仁留言提出宝贵意见
今天主要说说QT 的线程的两种实现方式
1、继承QThread 实现 虚函数 run(),在run()里面实现线程执行内容
movetoleftthread.h
class MoveToLeftThread : public QThread //继承
{
Q_OBJECT
public:
MoveToLeftThread();
bool threadRemark;//线程是否执行控制变量
protected:
void run();
signals:
void moveToLeft(); //给主线程传信号
public slots:
void stopThread();
};
movetoleftthread.cpp
MoveToLeftThread::MoveToLeftThread()
{
threadRemark=true;//默认可以持续执行
}
void MoveToLeftThread::run()
{
while(threadRemark)
{
emit moveToLeft();
msleep(500);
}
threadRemark=true;//线程执行结束后,恢复可执行状态
}
void MoveToLeftThread::stopThread() //主线程触发该槽函数,结束线程执行
{
threadRemark=false;
}
2、将线程执行放到 QObject 子类里,将QObject 子类对象 通过 moveToThread()方法,放到线程中,通过事件队列循环控制
movetorightthread.h
class MoveToRightThread : public QObject
{
Q_OBJECT
public:
explicit MoveToRightThread(QObject *parent = 0);
public slots:
void doWork();//线程执行内容
signals:
void resultReady();//传递给主线程,结束当前线程
void moveToRight();//控制信号
};
movetorightthread.cpp
MoveToRightThread::MoveToRightThread(QObject *parent) : QObject(parent)
{
}
void MoveToRightThread::doWork()
{
int count =0;
while(count<10)
{
count++;
emit moveToRight();
qDebug()<<"count "<<count;
Sleep(1000);
}
emit resultReady();
}
QuickWidget.h
class QuickWidget : public QQuickWidget
{
Q_OBJECT
public:
QuickWidget();
~QuickWidget();
void initConnection();
MoveToLeftThread *leftThread;
QThread rightThread;
signals:
void moveToLeft();
void moveToRight();
void resetCenter();
public slots:
void closeWindow();
void leftButtonEvent();
void centerButtonEvent();
void rightButtonEvent();
void stopMoveTOLeft();
void stopMoveToRight();
};
quickwidget.cpp
QuickWidget::QuickWidget()
{
QScreen *screen=qApp->primaryScreen();
rootContext()->setContextProperty("mainWidth",screen->size().width());
rootContext()->setContextProperty("mainHeight", screen->size().height());
rootContext()->setContextProperty("mainWidthCell",screen->size().width()/64);
rootContext()->setContextProperty("mainHeightCell", screen->size().height()/36);
setResizeMode(QQuickWidget::SizeRootObjectToView);
setSource(QUrl("qrc:/main.qml"));
setWindowFlags(Qt::FramelessWindowHint);
initConnection();
}
QuickWidget::~QuickWidget()
{
}
void QuickWidget::initConnection()
{
QQuickItem *root = this->rootObject();
connect(root,SIGNAL(closeWindow()),this,SLOT(closeWindow()));
connect(root,SIGNAL(leftButtonEvent()),this,SLOT(leftButtonEvent()));
connect(root,SIGNAL(centerButtonEvent()),this,SLOT(centerButtonEvent()));
connect(root,SIGNAL(rightButtonEvent()),this,SLOT(rightButtonEvent()));
connect(this,SIGNAL(moveToLeft()),root,SLOT(moveToLeft()));
connect(this,SIGNAL(moveToRight()),root,SLOT(moveToRight()));
connect(this,SIGNAL(resetCenter()),root,SLOT(resetCenter()));
leftThread = new MoveToLeftThread; //初始化
connect(leftThread,SIGNAL(moveToLeft()),root,SLOT(moveToLeft()),Qt::BlockingQueuedConnection);
//connect 的使用说明会放到专题讲,第五个参数 是连接的类型 阻塞队列连接
connect(root,SIGNAL(stopMoveTOLeft()),this,SLOT(stopMoveTOLeft()));
}
void QuickWidget::closeWindow()
{
this->close();
}
void QuickWidget::stopMoveTOLeft()
{
qDebug()<<"stopMoveTOLeft";
leftThread->stopThread();
leftThread->quit();
}
void QuickWidget::leftButtonEvent()
{
qDebug()<<tr("向左走");
// emit moveToLeft();
leftThread->start();
}
void QuickWidget::centerButtonEvent()
{
qDebug()<<tr("几米的世界");
emit resetCenter();
}
void QuickWidget::rightButtonEvent()
{
qDebug()<<tr("向右走");
MoveToRightThread *rightWorker = new MoveToRightThread;//实例化QObject对象
rightWorker->moveToThread(&rightThread);//移入线程
connect(&rightThread, &QThread::finished, rightWorker, &QObject::deleteLater);//线程结束,object对象销毁
connect(this, &QuickWidget::moveToRight, rightWorker, &MoveToRightThread::doWork);//主线程通知线程开始执行
connect(rightWorker,SIGNAL(moveToRight()),this->rootObject(),SLOT(moveToRight()));//
connect(rightWorker, &MoveToRightThread::resultReady, this, &QuickWidget::stopMoveToRight);
rightThread.start();//线程开始
emit moveToRight();//通知线程执行
}
void QuickWidget::stopMoveToRight()
{
rightThread.quit();//结束线程,同时会销毁Object对象
}
推荐使用第二种办法,保证线程的安全