在gui编程里,一个子函数的运行时间可能过长,界面就处于假死状态,原因是窗口是一个线程,子函数也在这个线程里,一些事件也要在这个线程里处理。
如果子函数运行时间过长,系统没有办法调用事件监听循环,gui就处于假死。一般有两种办法:
子函数事件不是很长,可以在子函数中间插入一些 QCoreApplication::processEvents
另一种方法就是把耗时的工作放到另一个线程里,通过信号槽来传递。这里介绍Qobject的moveToThread方法。
下面使用老板和员工的例子来讲,有两个BT老板,闲的蛋疼,安了个闹钟,每个一段时间查员工的岗。
代码如下:
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <iostream>
using namespace std;
#include <QString>
#include <QDebug>
#include <QThread>
class Worker : public QObject
{
Q_OBJECT
public:
Worker(QString name,QObject *parent=0);
~Worker();
public:
long runnum;
QString name;
public slots:
void run();
};
#endif // WORKER_H
#include "worker.h"
Worker::Worker(QString name,QObject *parent)
: name(name),QObject(parent)
{
runnum=0;
qDebug()<<"Hi,I am worker:"<<name<<"at thread number:"<<QThread::currentThread()<<endl;
}
Worker::~Worker()
{
}
void Worker::run()
{
runnum++;
qDebug()<<"I am"<<name<<"do not spy me so frequently boss! I am busy in my work...";
qDebug()<<"you have spy me "<<runnum<<" times!"<< "I am working at thread number :"<<QThread::currentThreadId()<<endl;
}
#include <QtCore/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);
//连接超时信号与槽
QObject::connect(boss1,SIGNAL(timeout()),&w1,SLOT(run()));
//
QTimer* boss2 = new QTimer;
boss2->setInterval(3000);
QThread* t2 = new QThread;
t2->start();
Worker w2("Lily");
w2.moveToThread(t2);
QObject::connect(boss2,SIGNAL(timeout()),&w2,SLOT(run()));
//启动定时器
boss1->start();
boss2->start();
return a.exec();
}