在进行桌面应用程序开发的时候,假设应用程序在某些情况下需要处理比较复杂的逻辑,如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个线程处理窗口事件,其他线程进行逻辑运算,多个线程各司其职,不仅可以提高用户体验还可以提升程序的执行效率。
在 qt 中使用了多线程,有些事项是需要额外注意的:
- 默认的线程在 qt 中称之为窗口线程,也叫主线程,负责窗口事件处理或者窗口控件数据的更新
- 子线程负责后台的业务逻辑处理,子线程中不能对窗口对象做任何操作,这些事情需要交给窗口线程处理
- 主线程和子线程之间如果要进行数据的传递,需要使用 qt 中的信号槽机制
1 线程类 QThread
1.1 常用共用成员函数
Qt中提供了一个线程类。通过这个类就可以创建子线程,Qt一共提供了两种创建子线程的方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
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);
bool QThread::wait(unsigned long time = ULONG_MAX);
|
1.2 信号槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
[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 静态函数
1 2 3 4 5 6 7 8 9 10
| [static] QThread *QThread::currentThread();
[static] int QThread::idealThreadCount();
[static] void QThread::msleep(unsigned long msecs); [static] void QThread::sleep(unsigned long secs); [static] void QThread::usleep(unsigned long usecs);
|
1.4 任务处理函数
1 2
| [virtual protected] void QThread::run();
|
这个 run() 是一个虚函数,如果想让创建的子线程执行某个任务,需要写一个子类让其继承 QThread,并且在子类中重写父类的 run() 方法,函数体就是对应的任务处理流程。另外,这个函数是一个受保护的成员函数,不能够在类的外部调用,如果想要让线程执行这个函数中的业务流程,需要通过当前线程对象调用槽函数 start() 启动子线程,当子线程被启动,这个 run() 函数就在线程内部被调用了。