QThread
https://www.cnblogs.com/ike_li/p/4709867.html
Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类转移到一个Thread里。
Qt4.8之前都是使用继承QThread的run这种方法,但是Qt4.8之后,Qt官方建议使用第二种方法。两种方法区别不大,用起来都比较方便,但继承QObject的方法更加灵活。这里要记录的是如何正确的创建一个线程,特别是如何正确的退出一个线程。
QThread
只有run
函数是在新线程里的 QThread
只有run
函数是在新线程里的 QThread
只有run
函数是在新线程里的
重要的事情说3遍!!!
,如果QThread
是在ui所在的线程里生成,那么QThread
的其他非run
函数都是和ui线程一样的,所以,QThread
的继承类的其他函数尽量别要有太耗时的操作,要确保所有耗时的操作都在run
函数里。
在UI线程下调用QThread
的非run
函数(其实也不应该直接调用run
函数,而应该使用start函数),和执行普通函数无区别,这时,如果这个函数要对QThread
的某个变量进行变更,而这个变量在run
函数里也会被用到,这时就需要注意加锁的问题,因为可能这个变量前几毫秒刚刚在run中调用,再调用时已经被另外的线程修改了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> #include<QThread> #include<QtCore> class MyThread : public QThread { Q_OBJECT public : explicit MyThread(QObject *parent = 0); ~MyThread(); public : void run(); bool stop= false ; signals: void NumberChanged( int number); }; #endif // MYTHREAD_H |
#include "mythread.h" MyThread::MyThread(QObject *parent) { } MyThread::~MyThread() { } void MyThread::run() { for(int i=0;i<1000;i++) { QMutex mutex; mutex.lock(); if(this->stop) { break; } else { mutex.unlock(); } emit NumberChanged(i); this->msleep(100); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include<mythread.h> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public : explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public : MyThread *mThread; private : Ui::MainWindow *ui; private slots: void onNumberChanged( int number); void on_btnStart_clicked(); void on_btnStop_clicked(); }; #endif // MAINWINDOW_H |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include<mythread.h> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public : explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public : MyThread *mThread; private : Ui::MainWindow *ui; private slots: void onNumberChanged( int number); void on_btnStart_clicked(); void on_btnStop_clicked(); }; #endif // MAINWINDOW_H |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include<mythread.h> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public : explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public : MyThread *mThread; private : Ui::MainWindow *ui; private slots: void onNumberChanged( int number); void on_btnStart_clicked(); void on_btnStop_clicked(); }; #endif // MAINWINDOW_H |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui( new Ui::MainWindow) { ui->setupUi( this ); mThread= new MyThread( this ); QObject::connect(mThread,SIGNAL(NumberChanged( int )), this ,SLOT(onNumberChanged( int ))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::onNumberChanged( int number) { ui->lblNumber->setText(QString::number(number)); } void MainWindow::on_btnStart_clicked() { mThread->start(); mThread->stop= false ; } void MainWindow::on_btnStop_clicked() { //mThread->stop=true; mThread->stop= true ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #ifndef MYOBJECT_H #define MYOBJECT_H #include <QObject> #include<QDebug> #include<QThread> #include<QLabel> class MyObject : public QObject { Q_OBJECT public : explicit MyObject(QObject *parent = 0); ~MyObject(); signals: public slots: void Thread1(); void Thread2(QLabel *lbl); void Thread3(); }; #endif // MYOBJECT_H |
#ifndef MYOBJECT_H #define MYOBJECT_H #include <QObject> #include<QDebug> #include<QThread> #include<QLabel> class MyObject : public QObject { Q_OBJECT public: explicit MyObject(QObject *parent = 0); ~MyObject(); signals: public slots: void Thread1(); void Thread2(QLabel *lbl); void Thread3(); }; #endif // MYOBJECT_H
#ifndef MYOBJECT_H #define MYOBJECT_H #include <QObject> #include<QDebug> #include<QThread> #include<QLabel> class MyObject : public QObject { Q_OBJECT public: explicit MyObject(QObject *parent = 0); ~MyObject(); signals: public slots: void Thread1(); void Thread2(QLabel *lbl); void Thread3(); }; #endif // MYOBJECT_H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui( new Ui::MainWindow) { ui->setupUi( this ); myobj= new MyObject; QThread *mythread= new QThread; myobj->moveToThread(mythread); mythread->start(); connect(mythread,SIGNAL(started()),myobj,SLOT(Thread1())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { myobj->Thread1(); } void MainWindow::on_pushButton_2_clicked() { myobj->Thread2(ui->label); } void MainWindow::on_pushButton_3_clicked() { myobj->Thread3(); } void MainWindow::on_pushButton_4_clicked() { qDebug()<<QThread::currentThreadId(); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2018-04-10 icp算法
2018-04-10 std::time(0)找不到