本文介绍两种在Qt子线程(非UI线程)中更新UI组件的常用方法。
1. 使用信号槽
这是一种非常常规的方式,通过自定义信号、槽,连接该信号和槽,在子线程中发送信号,在槽中更新 UI。
定义信号和槽:
1 | signals: |
在子线程中发送信号:
1 | // 连接信号 |
在槽函数中更新 UI:
1 | void UpdateUIInSubThread::onUpdateUi(int v) |
这种方式需要单独额外定义信号和槽,使用起来比较繁琐。
2. 使用invokeMethod
QMetaObject::invokeMethod 函数的原型如下:
1 | template <typename Functor, typename FunctorReturnType> bool QMetaObject::invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr) |
该函数可以在context
的事件循环中执行function
函数。
1 | std::thread t = std::thread([this]() { |
由于在子线程中更新 UI,因此信号和槽肯定使用的是 QueuedConnection 的连接方式,所以无法将FunctorReturnType
返回给调用者,否则会出现如下错误:
1 | QMetaObject::invokeMethod: Unable to invoke methods with return values in queued connections |
当然上述示例中也可以不使用 lambda 表达式,直接调用槽函数:
1 | std::thread t = std::thread([this]() { |