QT多线程方式二:
1)设定一个类,继承于QObject
2)类中设置一个线程函数(只有一个是线程函数),内部使用一个while循环
3)创建线程对象,不能指定父对象
4)创建QThread子线程对象
5)自定义线程类加入子线程
a) thread—>start() 只是开启了线程,并没有启动线程处理函数
b)线程函数的启动,必须要通过signal——slot
//线程函数类 mythread.h
1 #ifndef MYTHREAD_H 2 #define MYTHREAD_H 3 #include <QObject> 4 class mythread : public QObject 5 { 6 Q_OBJECT 7 public: 8 explicit mythread(QObject *parent = nullptr); 9 void myTimeOut(); //信号处理函数 10 void setStop(bool isStop = true); 11 signals: 12 void mysignal(); 13 public slots: 14 private: 15 bool isStop; 16 }; 17 #endif // MYTHREAD_H
//线程函数类 mythread.cpp
1 #include "mythread.h" 2 #include <QThread> 3 #include <QDebug> 4 mythread::mythread(QObject *parent) : QObject(parent) 5 { 6 isStop = false ; 7 } 8 void mythread::myTimeOut() 9 { 10 while ( !isStop ) { 11 QThread::sleep(1); 12 emit mysignal(); 13 qDebug()<<"子线程号: "<<QThread::currentThreadId(); 14 if(isStop) 15 break; 16 } 17 } 18 void mythread::setStop(bool flag) 19 { 20 isStop = flag ; 21 }
主体类 threadtest.h
1 #ifndef THREADTEST_H 2 #define THREADTEST_H 3 #include <QWidget> 4 #include "mythread.h" 5 namespace Ui { 6 class threadtest; 7 } 8 class threadtest : public QWidget 9 { 10 Q_OBJECT 11 public: 12 explicit threadtest(QWidget *parent = nullptr); 13 ~threadtest(); 14 void dealSignal(); 15 void threadStop(); 16 signals: 17 void startThread(); //启动子线程的信号 18 private slots: 19 void on_ButtonStart_clicked(); 20 void on_ButtonStop_clicked(); 21 private: 22 Ui::threadtest *ui; 23 mythread *myT; 24 QThread *thread; 25 }; 26 #endif // THREADTEST_H
主体类 threadtest.cpp
1 #include "threadtest.h" 2 #include "ui_threadtest.h" 3 #include <QThread> 4 #include <QDebug> 5 threadtest::threadtest(QWidget *parent) : 6 QWidget(parent), 7 ui(new Ui::threadtest) 8 { 9 ui->setupUi(this); 10 //动态分配空间,不能指定父对象 11 myT = new mythread(); 12 //创建子线程 13 thread = new QThread(this); 14 //自定义的线程加入子线程 15 myT->moveToThread(thread); 16 connect(myT,&mythread::mysignal,this,&threadtest::dealSignal); 17 qDebug()<<"主线程号: "<<QThread::currentThreadId(); 18 connect(this,&threadtest::startThread,myT,&mythread::myTimeOut); 19 connect(this,&threadtest::destroyed,this,&threadtest::threadStop); 20 //线程函数处理内部,不允许处理图形界面 21 //线程后台处理数据 22 //connect 第五个参数 的作用 ,只有在多线程才有意义 :1. 默认 2. 队列 3 直接 23 //默认的时候 24 //如果是多线程,默认使用队列 25 //如果是单线程,默认是使用直接 26 //队列方式:槽函数所在线程和接受者一样 27 //直接方式:槽函数所在线程和发送者一样 28 } 29 threadtest::~threadtest() 30 { 31 delete ui; 32 } 33 void threadtest::on_ButtonStart_clicked() 34 { 35 if(thread->isRunning() == true) 36 { 37 return; 38 } 39 thread->start(); //启动线程,但是没有启动线程函数 40 myT->setStop(false); 41 //不能直接调用线程处理函数,如果直接调用,那么线程处理函数和主线程在同一个线程 42 //myT->TimeOut(); //主线程号: 0xa2f8 子线程号: 0xa2f8 19:39:47: 程序异常结束。 43 //线程函数的启动只能通过signal-slot 44 emit startThread(); 45 } 46 void threadtest::dealSignal() 47 { 48 static int i = 0 ; 49 i++; 50 ui->lcdNumber->display(i); 51 } 52 void threadtest::on_ButtonStop_clicked() 53 { 54 if(thread->isRunning() == false) 55 { 56 return; 57 } 58 myT->setStop(true); 59 thread->quit(); 60 thread->wait(); 61 } 62 void threadtest::threadStop() 63 { 64 on_ButtonStop_clicked(); 65 delete myT; 66 }