(十七)线程
作者:互联网
QT4.7版本以前线程的使用
#include "mywidget.h" #include "ui_mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); mytimer = new QTimer(this); myt = new MyThread(this); connect(mytimer,&QTimer::timeout,this,[=](){ static int num = 0; ui->lcdNumber->display(num++); }); connect(ui->begin, &QPushButton::clicked, this, [=](){ if(mytimer->isActive() == true) { return; } // 启动定时器 mytimer->start(500); // ms // 启动线程 myt->start(); }); connect(myt,&MyThread::sigDone,mytimer,&QTimer::stop); } MyWidget::~MyWidget() { delete ui; }MyWidget.cpp
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include <QTimer> #include "mythread.h" namespace Ui { class MyWidget; } class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = nullptr); ~MyWidget(); private: Ui::MyWidget *ui; QTimer *mytimer; MyThread* myt; }; #endif // MYWIDGET_HMyWidget.h
#include "mythread.h" MyThread::MyThread(QObject *parent) : QThread(parent) { } void MyThread::run() { // 复杂的操作 sleep(5); emit sigDone(); }MyThread.cpp
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> #include <QThread> class MyThread : public QThread { Q_OBJECT public: explicit MyThread(QObject *parent = nullptr); protected: void run(); // 入口函数 -- 需要start()启动 signals: void sigDone(); public slots: }; #endif // MYTHREAD_HMyThread.h
QT4.7版本之后线程的使用
/* 多线程使用注意事项: * 1. 业务对象, 构造的时候不能指定父对象 * 2. 子线程中不能处理ui窗口(ui相关的类) * 3. 子线程中只能处理一些数据相关的操作, 不能涉及窗口 */
/* connect 的第 5 参数 * 1. 自动连接 -- 默认 * 多线程 -- 指定队列连接 * 单线程 -- 指定直接连接 * 2. 队列连接 -- 多线程 * 槽函数在信号接受者(receiver)所在的线程中执行 * 3. 直接连接 -- 单线程 * 信号和槽函数在同一个线程中执行 */
#include "mywidget.h" #include "ui_mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); mytimer = new QTimer(this); // 1. 业务对象 mywork = new MyWork(); // 2. 子线程类 pthread = new QThread(this); // 3. 移动业务对象到子线程 mywork->moveToThread(pthread); // 5. 子线程工作 connect(this, &MyWidget::sigWorking, mywork, &MyWork::doMyWork); connect(ui->begin, &QPushButton::clicked, this, &MyWidget::slotStart); connect(ui->stop, &QPushButton::clicked, this, &MyWidget::slotStop); // 定时器 connect(mytimer, &QTimer::timeout, this, &MyWidget::slotTimeout); connect(this,&MyWidget::destroyed, this, &MyWidget::slotCloseThread); } MyWidget::~MyWidget() { delete ui; } void MyWidget::slotStart() { if(mytimer->isActive() == true) { return; } if(pthread->isRunning()) { return; } mytimer->start(500); // 4. 启动子线程 pthread->start(); // 发信号, 让子线程工作 emit sigWorking(); } void MyWidget::slotStop() { mytimer->stop(); } void MyWidget::slotTimeout() { static int num = 0; ui->lcdNumber->display(num++); } void MyWidget::slotCloseThread() { mywork->setFlage(true); pthread->quit(); pthread->wait(); // 等待线程手头上的工作处理完成 }mywidget.cpp
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include <QTimer> #include "mywork.h" #include <QThread> namespace Ui { class MyWidget; } class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = nullptr); ~MyWidget(); // 开始按钮 void slotStart(); // 关闭按钮 void slotStop(); // 定时器 void slotTimeout(); // 关闭线程 void slotCloseThread(); signals: void sigWorking(); private: Ui::MyWidget *ui; QTimer* mytimer; MyWork* mywork; QThread* pthread; }; #endif // MYWIDGET_Hmywidget.h
#include "mywork.h" #include <QDebug> MyWork::MyWork(QObject *parent) : QObject(parent) { isStop = false; } void MyWork::doMyWork() { while(!isStop) { // 操作 QThread::sleep(1); // 当前线程处理操作用了1s // 每执行一次循环发一次信号 emit sigDone(); qDebug() << QThread::currentThread() << "sub thread"; // QMessageBox::aboutQt(NULL); if(isStop) { break; } } } void MyWork::setFlage(bool bl) { isStop = bl; }mywork.cpp
#ifndef MYWORK_H #define MYWORK_H #include <QObject> #include <QThread> class MyWork : public QObject { Q_OBJECT public: explicit MyWork(QObject *parent = nullptr); // 业务处理函数 void doMyWork(); void setFlage(bool bl); signals: void sigDone(); public slots: private: bool isStop; }; #endif // MYWORK_Hmywork.h
标签:十七,parent,void,ui,线程,MyWidget,include 来源: https://www.cnblogs.com/xiangtingshen/p/10793303.html