在gui编程里,一个子函数的运行时间可能过长,界面就处于假死状态,原因是窗口是一个线程,子函数也在这个线程里,一些事件也要在这个线程里处理。

如果子函数运行时间过长,系统没有办法调用事件监听循环,gui就处于假死。一般有两种办法:

子函数事件不是很长,可以在子函数中间插入一些 QCoreApplication::processEvents

另一种方法就是把耗时的工作放到另一个线程里,通过信号槽来传递。这里介绍Qobject的moveToThread方法。

下面使用老板和员工的例子来讲,有两个BT老板,闲的蛋疼,安了个闹钟,每个一段时间查员工的岗。

代码如下:

  1. #include <QCoreApplication>
  2. #include <QThread>
  3. #include <QTimer>
  4. #include <QObject>
  5. #include <QDebug>
  6. #include "worker.h"
  7. int main(int argc, char *argv[])
  8. {
  9. QCoreApplication a(argc, argv);
  10. qDebug()<<"main thread is :"<<QThread::currentThreadId()<<endl; //打印主线程的线程号

  11. QTimer *boss1 = new QTimer();
  12. boss1->setInterval(5000);
  13. QThread *t1=new QThread(); //来一个新的线程
  14. t1->start(); //启动线程
  15. Worker w1("Bob"); //创建一个对象
  16. w1.moveToThread(t1); //把这个对象移到线程t1里
  17. QObject::connect(boss1, SIGNAL(timeout()), &w1, SLOT(run())); //通过信号槽机制将boss1和worker1连接起来,每个一段时间查一次看看员工工作没
  18.  
  19. QTimer *boss2 =new QTimer();
    boss2->setInterval(3000);
  20. QThread *t2=new QThread(); //来一个新的线程
  21. t2->start(); //启动线程
  22. Worker w2("Stuart"); //创建一个对象
  23. w2.moveToThread(t2); //把这个对象移到线程t2里
  24. QObject::connect(boss2, SIGNAL(timeout()), &w2, SLOT(run()));
  25.  
  26. boss1->start();
  27. boss2->start();
  28.  
  29. return a.exec();
  30. }

worker类

注意的是worker类一定要继承Qobject

  1. #ifndef WORKER_H
  2. #define WORKER_H
  3.  
  4. #include <QObject>
  5. #include <iostream>
  6. class Worker : public QObject
  7. {
  8. Q_OBJECT
  9. public:
  10. explicit Worker(QString name, QObject *parent = nullptr);
  11. long runnum=0;
  12. QString name;
  13.  
  14. signals:
  15.  
  16. public slots:
  17. void run(void);
  18. };
  19.  
  20. #endif // WORKER_H
  1. #include "worker.h"
  2. #include <QDebug>
  3. #include <QThread>
  4. Worker::Worker(QString name ,QObject *parent) : name(name),QObject(parent)
  5. {
  6. qDebug()<<"Hi, I'm worker:"<<name<<" at thread number:"<<QThread::currentThreadId()<<endl;
  7. }
  8.  
  9. void Worker::run()
  10. {
  11. runnum++;
  12. qDebug()<<"I'm "<<name<<" don't spy me so frequently boss! I'm busy in my work..........";
  13. qDebug()<<"you have spy me "<<runnum<<" times!"<< "I'm working at thread num :"<<QThread::currentThreadId()<<endl;
  14. long s=1000;
  15. for (long i=0; i<s;i++){
  16.  
  17. }
  18.  
  19. }

运行后的结果:

  1. main thread is : 0x6be0
  2.  
  3. Hi, I'm worker: "Bob" at thread number: 0x6be0
  4.  
  5. Hi, I'm worker: "Stuart" at thread number: 0x6be0
  6.  
  7. I'm "Stuart" don't spy me so frequently boss! I'm busy in my work..........
  8. you have spy me 1 times! I'm working at thread num : 0x36c0
  9.  
  10. I'm "Bob" don't spy me so frequently boss! I'm busy in my work..........
  11. you have spy me 1 times! I'm working at thread num : 0x5ff0
  12.  
  13. I'm "Stuart" don't spy me so frequently boss! I'm busy in my work..........
  14. you have spy me 2 times! I'm working at thread num : 0x36c0
  15.  
  16. I'm "Stuart" don't spy me so frequently boss! I'm busy in my work..........
  17. you have spy me 3 times! I'm working at thread num : 0x36c0
  18.  
  19. I'm "Bob" don't spy me so frequently boss! I'm busy in my work..........
  20. I'm "Stuart" don't spy me so frequently boss! I'm busy in my work..........
  21. you have spy me 2 times! I'm working at thread num : 0x5ff0
  22.  
  23. you have spy me 4 times! I'm working at thread num : 0x36c0
  24.  
  25. I'm "Bob" don't spy me so frequently boss! I'm busy in my work..........
  26. I'm "Stuart" don't spy me so frequently boss! I'm busy in my work..........

不知道你们又遇到BT的老板吗。

QT多线程之---moveToThread用法的更多相关文章

  1. Qt 多线程使用moveToThread

    Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类用moveToThread函数转移到一个Thread里. Qt4.8之前都是使用继承QThre ...

  2. SeetaFaceQt:Qt多线程

    为什么要做多线程,说个最简单的道理就是我们不希望在软件处理数据的时候界面处于无法响应的假死状态.有些处理是灰常花时间的,如果把这样的处理放到主线程中执行,就会导致软件一条路走到底,要等到处理完才能接收 ...

  3. 【QT】 Qt多线程的“那些事”

    目录 一.前言 二.QThread源码浅析 2.1 QThread类的定义源码 2.2 QThread::start()源码 2.3 QThreadPrivate::start()源码 2.4 QTh ...

  4. QT多线程笔记

    1.QT多线程涉及到主线程和子线程之间交互大量数据的时候,使用QThread并不方便,因为run()函数本身不能接受任何参数,因此只能通过信号和槽的交互来获取数据,如果只是单方面简单交互数据还过得去, ...

  5. Qt多线程-QThread

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-QThread     本文地址:http://techieliang.com/2 ...

  6. 1.QT多线程使用小结

    开头 一个进程可以有一个或更多线程同时运行.线程可以看做是"轻量级进程",进程完全由操作系统管理,线程即可以由操作系统管理,也可以由应用程序管理. Qt 使用QThread来管理线 ...

  7. Qt 多线程和网络编程学习

    一,Qt多线程类学习 QThread类,开始一个新的线程就是开始执行重新实现QThread::run(),run()是默认现实调用exec(),QThread::start()开始线程的执行,run( ...

  8. [转] Qt 多线程学习

    Qt 多线程学习 转自:http://www.cnblogs.com/IT-BOY/p/3544220.html 最近的项目上用到了关于多线程的知识,自己也比较感兴趣,所以就拿了那本<C++ G ...

  9. 多线程中lock用法的经典实例

    多线程中lock用法的经典实例 一.Lock定义     lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.它可以把一段代码定义为互斥段(critical section),互斥段在一 ...

随机推荐

  1. layui-简单的登录注册界面

    register.html 源代码: <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  2. SSM-文件上传

    因为开发环境和线上环境系统不一样,所以需要区别环境 config.java 可以判断系统进行自动化的区别,我是手动去切换注释的 public class config { //public stati ...

  3. 「POJ1147」The Buses

    传送门 POJ Vjudge 解题思路 可以首先预处理一下可能成为一条线路的所有方案,然后把这些可能的方案按照长度降序排序,即按照路线上的时间节点从多到少排序. 因为这样我们就可以先确定更多的时刻的状 ...

  4. Opencv中常见的滤波方法

    滤波(模糊)的概念和作用: 图像滤波增强处理实质上就是运用滤波技术来增强图像的某些空间频率特征,以改善地物目标与领域或背景之间的灰度反差. 遥感系统成像过程中可能产生的”模糊”作用,常使遥感图像上某些 ...

  5. WebEx如何录制电脑内的声音

    WebEx如何录制电脑内的声音     事情是这样的,我需要参加一个网络课程,视频讲课的,但是呢,又因为自己白天需要干别的事,就想着怎么把视频录下来晚上回去看,找了WebEx录屏软件,尝试了下,录屏听 ...

  6. 小程序mdns+udpSocket实现电视推送

    起因:公司以前小程序推送架构为:小程序->接口->后台->socket->机顶盒client->socket->后台->接口->小程序,一系列接口才得到 ...

  7. 二十一 JDK注解&注解案例

    什么是注解? 注解和接口,类属于同一个级别 注解可以在变量.方法.类上加载 注解可以有属性也可以没有属性 注解是有作用范围(源码.编译期间,运行期间) 源码期间:例如String类上@Author  ...

  8. JDBC Connection Configuration配置正确,提示Error preloading the connection pool

    JDBC Connection Configuration配置正确,提示Error preloading the connection pool JDBC 请求报错,提示: 因为之前执行是正确的,这次 ...

  9. postgres 删除外部表

    drop external table if exists tableName;

  10. Java提升四:Stream流

    1.Stream流的定义 Stream是Java中的一个接口.它的作用类似于迭代器,但其功能比迭代器强大,主要用于对数组和集合的操作. Stream中的流式思想:每一步只操作,不存储. 2.Strea ...