Qt不能在线程函数操作UI

  Qt的官方文档虽然并没有明确说明,不能在子线程中操作UI,但是,因为Qt是事件循环机制,所有的UI事件都是在主线程中处理的,如果在子线程中直接操作UI,就会存在线程安全问题,严重时候会使程序挂掉。

  但是有些场景确实需要在子线程中操作UI怎么办?以下是几种常用的解决方案:
**  1. 使用信号槽机制**
**  这种方式是当子线程中需要对ui对象进行操作时,发出一个信号,在与之连接的槽中处理ui操作。信号和槽的连接方式必须是BlockingQueuedConnection 或QueuedConnection 的连接方式连接。**
**  2. 使用自定义event**
**  在子线程中通过QCoreApplication::postEvent 发出自定义的event,在对应的ui对象中重写customevent中处理自定义的event 。**
**  3. 使用QMetaObject::invokeMethod()函数**
**  该函数是一个静态函数,可以直接使用,用于调用对象的元对象方法 。该函数功能很强大,这里是用到了其可以在不同线程之间调用对象方法的特性。**

  如果是新代码,可以在程序设计之初就处理好子线程与UI操作之间的协调处理,这种情况比较好办,可以使用方法1和方法2进行处理。但是如果是维护历史代码,重新做设计肯定是不现实的,所以就需要使用方法3进行处理,在子线程中操作UI的代码段,修改为QMetaObject::invokeMethod函数调用,可以做到最小程度的代码修改,下面给出具体例子:

cpp 复制代码
// 在子线程中调用
int rowCount = 0;
REPORT_DE_INFO reportInfo;
bool b = QMetaObject::invokeMethod(this, "initTablewidget", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, rowCount), Q_ARG(REPORT_DE_INFO&, reportInfo));

  参数说明:

   参数1:调用对象指针

   参数2:调用的方法名

   参数3:连接方式,与信号槽连接函数connect的最后一个参数相同。对于这里是维护历史代码的场景,建议使用BlockingQueuedConnection,原来代码的执行逻辑一定是先执行完函数后才继续往下走,如果这里不给阻塞住,函数还没执行完,子线程就会继续往下走,很显然这与原来的代码逻辑并不相同,很可能会出现错误

   参数4:Q_RETURN_ARG宏,用来接收函数的返回值,宏的第1个参数是返回值类型,第2个参数是接收返回值的变量名

   参数5:Q_ARG宏,用来向函数传递参数,宏的第1个参数是函数参数的类型,第2个参数是传递参数的变量名,如果函数有多个参数,可以继续往下使用Q_ARG宏来传递

   返回值:bool类型,执行成功或者失败

   注意:执行的函数一定要是槽函数,否者回执行失败

相关推荐
油丶酸萝卜别吃3 小时前
utils.js 说明文档
开发语言·javascript·ecmascript
leisoo80975 小时前
100GBA股股票数据怎么存ClickHouseRedisMySQLJSON完整对比
大数据·linux·服务器·开发语言·python
不会代码的小猴6 小时前
21. 泛型编程上
开发语言·c++·笔记·算法
一只旭宝7 小时前
细讲C加加【9】C++ std::function与std::bind详解|仿函数、绑定器、类成员绑定、占位符、成员偏移指针
开发语言·c++·算法
coder!mq9 小时前
说几个常见的语法糖?
java·开发语言·算法
gugucoding9 小时前
38. 【Java】Stream API(下):高级操作与性能
java·开发语言
Lhan.zzZ9 小时前
在 Visual Studio 2022 中打造可扩展的动态链接库模块:从零搭建到原理解析
开发语言·c++·visual studio
心平气和量大福大10 小时前
android-实例-蒲公英-更新与安装-5-签名与生成APK
android·java·开发语言
码哥DFS10 小时前
构造函数、实例对象、对象原型 ----三者关系
开发语言·javascript·原型模式
quantdash_cc10 小时前
告别自建 Requests/BS4 网页爬虫:基于 QuantDash 搭建零维保的高性能量化行情流水线
开发语言·爬虫·python·pandas·量化·quantdash