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

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

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

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

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

代码如下:

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

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

worker类

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

#ifndef WORKER_H
#define WORKER_H #include <QObject>
#include <iostream>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QString name, QObject *parent = nullptr);
long runnum=0;
QString name; signals: public slots:
void run(void);
}; #endif // WORKER_H
#include "worker.h"
#include <QDebug>
#include <QThread>
Worker::Worker(QString name ,QObject *parent) : name(name),QObject(parent)
{
qDebug()<<"Hi, I'm worker:"<<name<<" at thread number:"<<QThread::currentThreadId()<<endl;
} void Worker::run()
{
runnum++;
qDebug()<<"I'm "<<name<<" don't spy me so frequently boss! I'm busy in my work..........";
qDebug()<<"you have spy me "<<runnum<<" times!"<< "I'm working at thread num :"<<QThread::currentThreadId()<<endl;
long s=1000;
for (long i=0; i<s;i++){ } }

运行后的结果:

main thread is : 0x6be0

Hi, I'm worker: "Bob"  at thread number: 0x6be0

Hi, I'm worker: "Stuart"  at thread number: 0x6be0

I'm  "Stuart"  don't spy me so frequently boss! I'm busy in my work..........
you have spy me 1 times! I'm working at thread num : 0x36c0 I'm "Bob" don't spy me so frequently boss! I'm busy in my work..........
you have spy me 1 times! I'm working at thread num : 0x5ff0 I'm "Stuart" don't spy me so frequently boss! I'm busy in my work..........
you have spy me 2 times! I'm working at thread num : 0x36c0 I'm "Stuart" don't spy me so frequently boss! I'm busy in my work..........
you have spy me 3 times! I'm working at thread num : 0x36c0 I'm "Bob" don't spy me so frequently boss! I'm busy in my work..........
I'm "Stuart" don't spy me so frequently boss! I'm busy in my work..........
you have spy me 2 times! I'm working at thread num : 0x5ff0 you have spy me 4 times! I'm working at thread num : 0x36c0 I'm "Bob" don't spy me so frequently boss! I'm busy in my work..........
I'm "Stuart" don't spy me so frequently boss! I'm busy in my work..........

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

最新文章

  1. 【sql】之查询昨天的记录
  2. Linux C/C++的编译
  3. iocp还是select
  4. Tempter of the Bone---hdu1010(dfs+剪枝)
  5. lua与 object-C 通信
  6. Hybrid App简介
  7. [Jsp]防止页面表单重复提交的解决方法
  8. 2 weekend110的hadoop的自定义排序实现 + mr程序中自定义分组的实现
  9. (转)LINUX的端口和服务
  10. C#学习日志 day 4 ------ 类相关---this指针以及相关关键字
  11. java怎样获取CPU占用率和硬盘占用率
  12. 功能测试话题分享-0323 Bug
  13. centos6.6 minimal cannot found a valid baseurl for repo :base
  14. poj1164 The Castle
  15. k8s 使用
  16. oracle 语句 笔记
  17. go遍历某个文件夹
  18. Java Scanner Readable
  19. 转MySQL常见错误分析与解决方法总结
  20. 函数的扩展--ES6

热门文章

  1. 基于PIL模块创建验证码图片
  2. sklearn实现多分类逻辑回归
  3. Golang编程的工程管理
  4. 水费管理系统-ER图和流程图
  5. beanstalkd队列
  6. STM32+Nokia5110LCD
  7. 小程序包大小超过2M的解决方法
  8. Linux-initramfs
  9. 008、MySQL日期时间格式化输出
  10. 008-PHP定义数组