当前位置:   article > 正文

Qt线程的四种创建方式_qt 线程

qt 线程

 Qt中主线程负责界面显示和窗口控件的数据更新,子线程负责逻辑业务处理和数据计算,子线程不能对窗口有任何操作,子线程可通过信号槽来将数据传递给主线程。

1、子线程继承QThread

子线程继承QThread,然后重写run()函数来执行子线程

每一个子业务逻辑都可继承一个QThread来实现多线程

  1. m_thread = new MyThread;
  2. connect(m_thread, &MyThread::signalsThreadCalNum, this, [=](int num){
  3. ui->label->setNum(num);
  4. });
  5. connect(ui->pushButton_start, &QPushButton::clicked, m_thread, [=](){
  6. m_thread->start();
  7. });
  8. connect(ui->pushButton_stop, &QPushButton::clicked, this, [=](){
  9. m_thread->Stop();
  10. });
  1. class MyThread:public QThread
  2. {
  3. Q_OBJECT
  4. //....
  5. protected:
  6. void run();
  7. }
  8. void MyThread::run()
  9. {
  10. int n = 0;
  11. while(n < 100000)
  12. {
  13. emit signalsThreadCalNum(n++);
  14. QThread::usleep(1);
  15. }
  16. }

2、使用moveToThread

(1)任务类Task需要继承QObject,然后写一个执行任务的函数。

(2)创建一个QThread线程,然后调用moveToThread将对象移动到创建的子线程对象中

(3)启动子线程即可

  1. //创建子线程
  2. m_thread = new QThread;
  3. m_work = new MyWork;
  4. //将工作的类对象转移到创建的子线程对象中
  5. m_work->moveToThread(m_thread);
  6. //启动线程
  7. m_thread->start();
  8. //这种写法是错误的,界面卡顿,个人理解:接受者是this,相当于mainwiodnw调用
  9. // connect(ui->pushButton_start, &QPushButton::clicked, this, [=](){
  10. // m_work->Work();
  11. // });
  12. //ok
  13. connect(ui->pushButton_start, &QPushButton::clicked, m_work, [=](){
  14. m_work->Start();
  15. });
  16. connect(ui->pushButton_stop, &QPushButton::clicked, this, [=](){
  17. m_work->Stop();
  18. });
  19. connect(m_work, &MyWork::signalsThreadCalNum, this, [=](int num){
  20. ui->label->setNum(num);
  21. });
  1. class MyWork:public QObject
  2. {
  3. //......
  4. }
  5. void MyWork::Work()
  6. {
  7. int n = 0;
  8. while(n < 1000)
  9. {
  10. if(m_stop)
  11. break;
  12. emit signalsThreadCalNum(n++);
  13. QThread::usleep(1);
  14. }
  15. }

 3、使用QtConcurrent

(1)pro中需要加上 QT += concurrent

(2)任务类中重写run()函数

  1. MyThread *mythread = new MyThread;
  2. connect(ui->pushButton_start, &QPushButton::clicked, this, [=](){
  3. QtConcurrent::run(mythread, &MyThread::Work);
  4. });
  5. connect(mythread, &MyThread::signalsThreadCalNum, this, [=](int num){
  6. ui->label->setNum(num);
  7. });
  8. connect(ui->pushButton_stop, &QPushButton::clicked, this, [=](){
  9. mythread->Stop();
  10. });
  1. void MyThread::Work()
  2. {
  3. m_stop = false;
  4. int n = 0;
  5. while(n < 100000)
  6. {
  7. if(m_stop)
  8. break;
  9. emit signalsThreadCalNum(n++);
  10. QThread::usleep(1);
  11. }
  12. }

4、使用线程池

使用QRunnable和QThreadPool

(1)任务类需要继承QRunnable,需要使用信号槽的话可多重继承QObject

(2)重写run函数

(3)使用QThreadPool::globalInstance()->start(QRunable *)来启动线程池

  1. // 线程池初始化,设置最大线程池数
  2. QThreadPool::globalInstance()->setMaxThreadCount(4);
  3. //创建任务
  4. MyThread *mythread = new MyThread;
  5. //start启动线程池
  6. connect(ui->pushButton_start, &QPushButton::clicked, this, [=](){
  7. QThreadPool::globalInstance()->start(mythread);
  8. mythread->Start();
  9. });
  10. connect(mythread, &MyThread::signalsThreadCalNum, this, [=](int num){
  11. ui->label->setNum(num);
  12. });
  13. connect(ui->pushButton_stop, &QPushButton::clicked, this, [=](){
  14. mythread->Stop();
  15. });
  1. /*
  2. * 线程池使用需要继承QRunnable
  3. */
  4. class MyThread : public QObject, public QRunnable
  5. {
  6. //.....
  7. }
  8. MyThread::MyThread(QObject *parent) : QObject(parent), QRunnable()
  9. {
  10. setAutoDelete(true);
  11. }
  12. void MyThread::run()
  13. {
  14. m_stop = false;
  15. int n = 0;
  16. while(n < 100000)
  17. {
  18. if(m_stop)
  19. break;
  20. emit signalsThreadCalNum(n++);
  21. QThread::usleep(1);
  22. }
  23. }

5、线程池中可不采用多重继承QObject,可采用

QMetaObject::invokeMethod来实现

mainwindow.h中添加 

  1. Q_INVOKABLE void Show(int num);

 mainwindow.cpp

  1. //mainwindow.cpp
  2. // 线程池初始化,设置最大线程池数
  3. QThreadPool::globalInstance()->setMaxThreadCount(4);
  4. //创建任务
  5. MyThread *mythread = new MyThread(this);
  6. //start启动线程池
  7. connect(ui->pushButton_start, &QPushButton::clicked, this, [=](){
  8. QThreadPool::globalInstance()->start(mythread);
  9. mythread->Start();
  10. });
  11. connect(ui->pushButton_stop, &QPushButton::clicked, this, [=](){
  12. mythread->Stop();
  13. });
  14. void MainWindow::Show(int num)
  15. {
  16. ui->label->setNum(num);
  17. }

 子线程中

  1. void MyThread::run()
  2. {
  3. m_stop = false;
  4. int n = 0;
  5. while(n < 100000)
  6. {
  7. // if(m_stop)
  8. // break;
  9. QMetaObject::invokeMethod(m_pObj, "Show", Q_ARG(int, n++));
  10. //emit signalsThreadCalNum(n++);
  11. QThread::usleep(1);
  12. }
  13. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/104545
推荐阅读
相关标签
  

闽ICP备14008679号