在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑,如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个线程处理窗口事件,其他线程进行逻辑运算,多个线程各司其职,不仅可以提高用户体验,还可以提升程序的执行效率。
在 qt 中使用了多线程,有些事项是需要额外注意的:
- 默认的线程在Qt中称之为窗口线程,也叫主线程,负责窗口事件处理或者窗口控件数据的更新
- 子线程负责后台的业务逻辑处理,子线程中不能对窗口对象做任何操作,这些事情需要交给窗口线程处理
- 主线程和子线程之间如果要进行数据的传递,则需要使用Qt中的信号槽机制
一、QT多线程实现方法(1)- 基于QThread
- 创建subThread线程类,继承QThread类
- 重写父类的run()方法,即具体要执行的任务
- 主线程中创建子线程对象,调用start()方法启动子线程
二、QT多线程实现方法(2)- 基于QObject
- 创建工作类,继承QObject类
- 添加一个公共的成员函数,函数体就是子线程要执行的业务逻辑(后面把这个任务函数作为槽函数使用)
- 主线程中创建子线程对象
- 创建工作类对象(注意不能给他指定父对象)
- 将工作类对象移动到创建的子线程的对象中,需要调用QObject的moveToThread()方法
- 启动子线程,调用start()方法,但此时线程虽然启动了,但移动到线程中的对象没有工作
- 调用工作类对象的工作函数,让这个函数执行业务
第二种方法更灵活,一个工作类可以有多个工作函数,多个工作对象也可以移动到同一个子线程中,可以人为控制指定线程执行指定任务。在第一种方法中,如果run函数需要传入的数据,可以通过信号槽机制+成员变量的形式实现接收,工作函数run函数是不能直接传入参数的;而在第二种方法中,工作函数是可以有参数的,可以通过信号槽机制直接传入数据,而不用再定义成员变量。
第一种方法简单,只需要书写线程类,重写run函数,然后在主线程中创建子线程对象,通过这个子线程对象调用start方法工作。弊端就是,如果需求、任务足够多,写入到run函数中,判定就复杂,run函数也越臃肿,因此在任务简单、少的情况下使用第一种方法
需要注意的一个点,使用connect(发出者,信号,接收者,处理函数)时,
connect(gen,&Generate::sendArray