QT使用多线程的两种方法

两种方法:

  • 继承QThread类,重写run方法(QT4.8之前使用)
  • 自定义一个继承QObject的类转移到Thread中。和线程的交互通过信号和槽(实际上其实是通过事件)联系,QT4.8之后,官方建议这种方法)

为什么使用线程:?
举个例子:如果我们在写GUI程序的时候,如果某处的数据,计算比较复杂,当前主线程就会卡在这里,在具体表现就是界面会卡住。所以在这个时候多线程就起到了关键的作用, 我们将复杂的逻辑运算交给线程,由线程在后台处理。(注意:线程不能操作图形界面,他的线程任务是在后天进行数据运算等。

使用方法一的步骤:

  • 创建线程类,继承QThread
  • 重写run函数(尽量把复杂的逻辑,计算放在run函数中。)
  • 主线程中创建线程对象,调用start函数启动线程
    只有run函数在新线程中,其余都在主线程内

方法二:

QObject是Qt框架的基本类,但凡涉及到信号槽有关的类都是继承于QObject。QObject是一个功能异常强大的类,它提供了Qt关键技术信号和槽的支持以及事件系统的支持,同时它提供了线程操作的接口,也就是QObject是可以选择不同的线程里执行的。

QObject的线程转移函数是:void moveToThread(QThread * targetThread) ,通过此函数可以把一个顶层Object(就是没有父级)转移到一个新的线程里。

用QObject来实现多线程有个非常好的优点,就是默认就支持事件循环(Qt的许多非GUI类也需要事件循环支持,如QTimer、QTcpSocket),QThread要支持事件循环需要在QThread::run()中调用QThread::exec()来提供对消息循环的支持,否则那些需要事件循环支持的类都不能正常发送信号,因此如果要使用信号和槽,那就直接使用QObject来实现多线程。

使用QObject创建多线程的方法如下:

  • 写一个继承QObject的类,对需要进行复杂耗时逻辑的入口函数声明为槽函数
    此类在旧线程new出来,不能给它设置任何父对象。
  • 同时声明一个QThread对象,在官方例子里,QThread并没有new出来,这样在析构时就需要调用QThread::wait(),如果是堆分配的话, 可以通过deleteLater来让线程自杀
  • 把obj通过moveToThread方法转移到新线程中,此时object已经是在线程中了
    把线程的finished信号和object的deleteLater槽连接,这个信号槽必须连接,否则会内存泄漏
  • 正常连接其他信号和槽(在连接信号槽之前调用moveToThread,不需要处理connect的第五个参数,否则就显示声明用Qt::QueuedConnection来连接)
    初始化完后调用’QThread::start()'来启动线程.
  • 在逻辑结束后,调用QThread::quit退出线程的事件循环

你可能感兴趣的:(QT学习)