ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Qt多线程(二)

2019-02-27 22:49:41  阅读:307  来源: 互联网

标签:include Qt thread void MyThread 线程 myWidget 多线程


Qt多线程(二)

     上一篇通过继承QThread类,重写run()虚函数实现多线程应用程序,这一篇通过另一种方式实现Qt的多线程应用程序编程。实现功能为线程定时器的例子。

  1)新建工程后,添加线程类MyThread,基类为QObject;

//MyThread.h
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> class MyThread : public QObject { Q_OBJECT public: explicit MyThread(QObject *parent = 0); //线程处理函数 void myTimeout(); void setFlag(bool flag = true); signals: void mySignal(int *); public slots: private: bool bIsStop; //控制线程的启停 为真停止 }; #endif // MYTHREAD_H

 

//MyThread.cpp
#include "mythread.h" #include <QThread> #include <QDebug> MyThread::MyThread(QObject *parent) : QObject(parent) { bIsStop = false; } void MyThread::myTimeout() { static int a = 0; while(!bIsStop)
   //while(1) { a++; QThread::sleep(1); emit mySignal(&a); qDebug()<<"子线程 id="<<QThread::currentThread(); } } void MyThread::setFlag(bool flag) { bIsStop = flag; }

 

  2)在主线程中启动子线程

//主线程头文件
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include "mythread.h" #include <QThread> namespace Ui { class myWidget; } class myWidget : public QWidget { Q_OBJECT public: explicit myWidget(QWidget *parent = 0); ~myWidget(); private slots: void on_startButton_clicked(); void on_stopButton_clicked(); void dealCloseWnd(); void dealSignal(int *); signals: void startThread(); //启动子线程信号,必须通过信号-槽的方式启动线程函数 private: Ui::myWidget *ui; MyThread *myT; QThread *thread; }; #endif // MYWIDGET_H

 

//主线程cpp
#include "mywidget.h" #include "ui_mywidget.h" #include <QDebug> myWidget::myWidget(QWidget *parent) : QWidget(parent), ui(new Ui::myWidget) { ui->setupUi(this); //1)动态分配空间,不能指定父对象 myT = new MyThread; //2)创建子线程 thread = new QThread(this); //3)把自定义的线程加如到子线程中 myT->moveToThread(thread); connect(myT,SIGNAL(mySignal(int*)),this,SLOT(dealSignal(int*))); qDebug()<<"主线程 id="<<QThread::currentThread();
  //4)启动线程函数信号-槽连接 connect(this,&myWidget::startThread,myT,&MyThread::myTimeout);
connect(this,&myWidget::destroyed,this,&myWidget::dealCloseWnd); //线程处理函数内部不允许操作图形界面 //connect的第5个参数,表示连接方式:默认是队列 ,直接 //多线程才有意义 //默认的时候,如果是多线程,默认使用队列 //如果是单线程,默认使用直接方式 //队列方式:槽函数所在的线程和接收者一样(第4个参数和第3个参数) //直接方式:槽函数所在线程和发送者一样(第4个参数和第1个线程) //通过判断类来判断是多线程还是单线程 } myWidget::~myWidget() { delete ui; } void myWidget::dealCloseWnd() { myT->setFlag(true); thread->quit(); thread->wait(); delete myT; } void myWidget::dealSignal(int *a) { //static int a = 0; //a++; ui->lcdNumber->display(*a); } void myWidget::on_startButton_clicked() { if(thread->isRunning() == true) { return; } //启动线程,但是没有启动线程处理函数 thread->start(); //不能直接调用线程处理函数 //直接调用,导致线程处理函数和主线程是在同一个线程 //myT->myTimeout(); myT->setFlag(false); emit startThread(); } void myWidget::on_stopButton_clicked() { if(thread->isRunning() == false) { return; } //通过使用flag标志控制线程停止 myT->setFlag(true); thread->quit(); thread->wait(); }

 

        需要注意:1)例子中通过使用flag标志在控制线程函数的启动和停止,如果不使用该标志位控制线程,当调用thread->quit()和thread->wait()后线程函数仍然在执行,原因是在执行thread->quit()和thread->wait()后,只用线程函数的任务处理完后,线程函数才会停止工作,而线程函数为死循环,所以会一直执行下去。同样道理在窗口关闭时也需要使用标志停止线程函数。

    2)启动线程必须使用信号-槽方式,不能直接调用线程处理函数;

    3)线程类可以定义多个函数,但是有且只能有一个线程处理函数,本例中void MyThread::myTimeout();

 

 

标签:include,Qt,thread,void,MyThread,线程,myWidget,多线程
来源: https://www.cnblogs.com/Forward-Forever/p/10447597.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有