背景引言[ GUI主线程 +子线程]
跟C++11中很像的是,Qt中使用QThread来管理线程,一个QThread对象管理一个线程,在使用上有很多跟C++11中相似的地方,但更多的是Qt中独有的内容。另外,QThread对象也有消息循环exec()函数,即每个线程都有一个消息循环,用来处理自己这个线程的事件。
QCoreApplication::exec()总是在主线程(执行main()的线程)中被调用,在GUI程序中,主线程也称为GUI线程,是唯一允许执行GUI相关操作的线程,所有要创建的其他线程任务都要依附于主线程。因此,若要创建一个QThread线程任务,前提是必须创建QApplication(or QCoreApplication)对象。
GUI应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个线程处理窗口事件,其他线程进行逻辑运算,多个线程各司其职,不仅可以提高用户体验还可以提升程序的执行效率。
在 qt 中使用了多线程,有些事项是需要额外注意:
- 默认的线程在Qt中称之为窗口线程,也叫主线程即GUI线程,负责窗口事件处理或者窗口控件数据的更新
- 子线程负责后台的业务逻辑处理,子线程中不能对窗口对象做任何操作,这些事情需要交给窗口线程处理
- 主线程和子线程之间如果要进行数据的传递,需要使用Qt中的信号槽机制
一、QThread 线程类
Qt 中提供了一个QThread 线程类【继承于QObject,区别于QRunnable】,通过这个类就可以创建子线程了。
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
1.1 常用成员函数
// 构造函数,父类QObject
QThread::QThread(QObject *parent = Q_NULLPTR);
// 判断线程中的任务是不是处理完毕了
bool QThread::isFinished() const;
// 判断子线程是不是在执行任务
bool QThread::isRunning() const;
// 获取、设置线程的优先级
Priority QThread::priority() const;
void QThread::setPriority(Priority priority);
优先级:
QThread::IdlePriority --> 最低的优先级
QThread::LowestPriority
QThread::LowPriority
QThread::NormalPriority
QThread::HighPriority
QThread::HighestPriority
QThread::TimeCriticalPriority --> 最高的优先级
QThread::InheritPriority --> 子线程和其父线程的优先级相同, 默认是这个
// 退出线程, 停止底层的事件循环
// 退出线程的工作函数
void QThread::exit(int returnCode = 0);
// 调用线程退出函数之后, 线程不会马上退出因为当前任务有可能还没有完成, 调回用这个函数是
// 等待任务完成, 然后退出线程, 一般情况下会在 exit() 后边调用这个函数
bool QThread::wait(unsigned long time = ULONG_MAX);
1.2 信号槽
//等同于exit() 效果,之后也要调 wait() 函数
[slot] void QThread::quit();
// 启动子线程
[slot] void QThread::start(Priority priority = InheritPriority);
// 函数用于强制结束线程,不保证数据完整性和资源释放,慎用
[slot] void QThread::terminate();
// 线程中执行完任务后, 发出该信号
[signal] void QThread::finished();
// 开始工作之前发出这个信号, 一般不使用
[signal] void QThread::started();
1.3 静态函数
// 当前执行线程的QThread指针对象
[static] QThread *QThread::currentThread();
// 返回系统上运行的理想线程数 == 和当前电脑的 CPU 核心数相同
[static] int QThrea