QT嵌入式开发Qthread

QThread的两种使用方法

  1. 不使用事件循环。官方manual介绍的一种方法
    1) 子类化QThread
    2) 重载run函数,run函数内有一个死循环
    3) 设置一个标记位来控制死循环的退出
    如果使用这个方法,那么QThread::quit()就没有效果,因为这个线程不需要事件循环。这个时候使用QT不推荐的terminate()

  2. 使用事件循环
    1) 子类化QThread
    2) 重载run使其调用QThread::exec()
    3) 并为该类定义信号和槽,这样一来,由于slot函数并不会在新开的thread运行,很多人为了解决这个问题在构造函数中调用moveToThread(this)

QThread应该被看做是操作系统线程的接口或控制点,而不应该包含需要在新线程中运行的代码。需要运行的代码应该放到一个QObject子类中,然后将该子类的对象moveToThread到新线程中。

QThread分析

QThread代表一个线程,我们可以重新实现QThread::run()。要新建一个线程,我们应该先继承QThread并重新实现run()函数。

注意:

  1. 必须在创建QThread对象之前创建QApplication(继承自QCoreApplication和QGuiApplication)
  2. QCoreApplication::exec()必须只能从主线程调用,不能从QThread线程调用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyThread : public QThread {
Q_OBJECT
public:
MyThread(QObject * parent = NULL);
~MyThread();

protected:
void run();
}

void MyThread::run(){
for(int cout = 0; count < 20; count++){
sleep(1);
}
qDebug("finish!");
}

我们可以在这样调用:

1
2
3
MyThread thread;
thread.start();
thread.wait(); //必须要加,主线程要等到MyThread线程结束才能结束

当然我们开的线程可能要运行很久,会卡住主线程,可以使用QeventLoop进行轮转。

1
2
3
4
5
6
MyThread thread;
thread.start();
QeventLoop;
connect(&thread, SIGNAL(finished()), &event, SLOT(quit()));
thread.wait(1);
eventLoop.exec();