这个例子是,点击开始按钮,数字累加,点击停止按钮,数字不动。
1,新建一个类,里面是子线程的内容
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> class MyThread : public QObject { Q_OBJECT public: explicit MyThread(QObject *parent = nullptr); //线程处理函数 void myTimeout(); void setFlag(bool flag = false); signals: void mySignal(); public slots: private: bool isStop; }; #endif // MYTHREAD_H
#include "mythread.h" #include <QThread> #include <QDebug> MyThread::MyThread(QObject *parent) : QObject(parent) { isStop = false; } void MyThread::myTimeout() { while(isStop == false) { QThread::sleep(1); emit mySignal(); qDebug()<<"子线程号: "<<QThread::currentThread(); if(isStop == true) { break; } } } void MyThread::setFlag(bool flag) { isStop = flag; }
2,主线程中创建QTread 对象,然后将子线程类通过moveToThread()中来
并且不直接调用子程序(子线程),通过主程序发出一个信号,然后子程序接受到信号,开始运行
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include "mythread.h" #include <QDebug> namespace Ui { class MyWidget; } class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = 0); ~MyWidget(); void dealSignal(); void dealClose(); signals: void startThread();//启动子线程 private slots: void on_startBtn_clicked(); void on_stopBtn_clicked(); private: Ui::MyWidget *ui; MyThread *myT; QThread *thread; }; #endif // MYWIDGET_H
#include "mywidget.h" #include "ui_mywidget.h" #include <QThread> MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); //动态分配空间,不能指定父对象 myT = new MyThread; //创建子线程 thread = new QThread(this); //把自定义线程加入到子线程中 myT->moveToThread(thread); connect(myT,&MyThread::mySignal,this,&MyWidget::dealSignal); qDebug()<<"主线程号: "<<QThread::currentThread(); connect(this,&MyWidget::startThread,myT,&MyThread::myTimeout); connect(this,&MyWidget::destroyed,this,&MyWidget::dealClose); //线程处理函数内部,不允许操作图形界面 //connect()第五个参数的作用,连接方式:默认,队列,直接 //多线程才有意义 //默认的时候,如果是多线程,默认使用队列,如果是单线程,默认是用直接方式 //队列:槽函数所在线程和接受者一样 //直接:槽函数所在线程和发送者一样 } void MyWidget::dealClose() { on_stopBtn_clicked(); delete myT; } void MyWidget::dealSignal() { static int i = 0; i++; ui->lcdNumber->display(i); } MyWidget::~MyWidget() { delete ui; } void MyWidget::on_startBtn_clicked() { if(thread->isRunning() == true) { return; } //启动线程,但是没有启动线程 thread->start(); myT->setFlag(false); //不能直接调用线程处理函数,直接调用导致线程处理函数和主线程在同一个线程 //myT->myTimeout(); //错的 //只能通过 signal-slot方式调用 emit startThread(); } void MyWidget::on_stopBtn_clicked() { if(thread->isRunning() == false) { return; } myT->setFlag(true); thread->quit(); thread->wait(); }