Qt 中使用 moveToThread 多线程踩坑记录

关于QT Widget 其它文章请点击这里:     QT Widget


今天在使用 Qt 的 moveToThread 实现多线程时,遇到了两个常见的坑,在这里记录一下,供自己和大家参考。

一、继承于QWidget 的控件不能在子线程中运行

Qt 的规定是:所有 UI 操作必须在主线程中执行。因此,QWidget 及其子类只能在主线程中创建和更新,不能移动到子线程中,也不能在子线程中直接操作 UI。

错误示例:

以下代码试图将继承自 QWidget 的 CompWord 移动到子线程:

class CompWorkBase : public QWidget
...
class CompWord :  public CompWorkBase
...
CompWord *_cmp_word = new CompWord(ui->wgt_Work);
QThread* _workerThread = new QThread();
_cmp_word->moveToThread(_workerThread);

运行后报错:

QObject::moveToThread: Cannot move objects with a parent

这是因为 CompWord 继承自 QWidget,而 QWidget 的实例必须在主线程中运行,因此不能将 _cmp_word 移动到子线程。

二、 QAxObject(以及 COM 组件)不能在子线程中实例化

在将 CompWord 的界面与逻辑分离后,又遇到了第二个坑:QAxObject 不能在子线程中实例化。这是由于 COM 的限制,默认情况下,COM 对象的创建和调用必须在主线程中进行。

原因:

COM 对象(如 Microsoft Word 的接口)基于单线程单元(STA,Single-Threaded Apartment)模型。STA 模型要求 COM 对象的创建和使用必须在同一个线程中进行,而该线程通常是 GUI 主线程。

如果在子线程中实例化 QAxObject,会导致 QAxBase::setControl 方法失败。

错误示例:

	...ReportWorker * _reportWorker = new ReportWorker();QThread*  _threadWorker = new QThread();_reportWorker->moveToThread(_threadWorker);// 连接信号槽connect(_threadWorker, &QThread::started, _reportWorker, &ReportWorker::reportInit);     // 线程初始化_threadWorker->start();

子线程的初始化逻辑如下:

void ReportWorker::reportInit() {wordApp = std::make_unique<QAxObject>("Word.Application");
}

运行后报错:

QAxBase::setControl: requested control Word.Application could not be instantiated
Failed to initialize Word.Application.

这说明 COM 对象(如 QAxObject)的实例化必须在主线程完成。


关于QT Widget 其它文章请点击这里:     QT Widget

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/67083.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity Protobuf实践

官方文档&#xff1a;https://protobuf.com.cn/overview/ 1. 获取Protobuf&#xff1a; 1.1 通过NuGet包管理器&#xff1a; 拷贝dll&#xff1a; 选择.net2.0的dll&#xff1a; 导入Unity Plugins目录&#xff1a; 1.2 下载源码并生成dll&#xff1a; GitHub - protocolbuf…

【微服务】面试 4、限流

微服务限流技术总结 一、微服务业务面试题引入 在微服务业务面试中&#xff0c;限流是重要考点&#xff0c;常与分布式事务、分布式服务接口幂等解决方案、分布式任务调度等一同被考查。面试官一般会询问项目中是否实施限流及具体做法&#xff0c;回答需涵盖限流原因、采用的方…

Java Bean Validation 不适用Spring的情况下自定义validation注解

Java Bean Validation&#xff08;也称为 JSR 380&#xff0c;为 Bean Validation 2.0 规范&#xff09;提供了一套基本的注解&#xff0c;用于定义和验证 Java Bean 的属性。例如&#xff1a; NotNull&#xff1a;属性不能为空 Size&#xff1a;字符串、集合或数组的大小有约…

VScode 配置 C语言环境

遇到的问题集合 mingw官方下载网站&#xff08;https://sourceforge.net/projects/mingw-w64/files/&#xff09;更新之后&#xff0c;与网上大多数教程上写的界面不同了。 网上大多数教程让下载这个&#xff1a; 但是现在找不到这个文件。 写hello.c文件时&#xff0c;报错&…

语音技术与人工智能:智能语音交互的多场景应用探索

引言 近年来&#xff0c;智能语音技术取得了飞速发展&#xff0c;逐渐渗透到日常生活和各行各业中。从语音助手到智能家居控制&#xff0c;再到企业客服和教育辅导&#xff0c;语音交互正以前所未有的速度改变着人机沟通的方式。这一变革背后&#xff0c;人工智能技术无疑是关键…

前端依赖安装指南

前端依赖安装指南 一、NVM管理工具安装 1.在 Windows 上安装 下载 NVM for Windows 的安装程序&#xff1a;(最新版本可以在 nvm-windows Releases 页面 找到)运行下载的安装程序并按步骤操作。 2.配置 NVM exe安装自动配置环境变量 3. 验证 NVM 安装 验证 NVM 是否成功…

使用sqlplus的easy connect时如何指定是链接到shared server还是dedicated process

在oracle配置了shared server的情况下 可以使用 :shared来指定链接到shared server也可以默认不指定 不指定的情况下会默认链接到shared server 如果想链接到 dedicated process 则必须显式指定链接到dedicated process server type的类型包括DEDICATED, SHARED, or POOLED. […

26个开源Agent开发框架调研总结(2)

根据Markets & Markets的预测&#xff0c;到2030年&#xff0c;AI Agent的市场规模将从2024年的50亿美元激增至470亿美元&#xff0c;年均复合增长率为44.8%。 Gartner预计到2028年&#xff0c;至少15%的日常工作决策将由AI Agent自主完成&#xff0c;AI Agent在企业应用中…

IOS HTTPS代理抓包工具使用教程

打开抓包软件 在设备列表中选择要抓包的 设备&#xff0c;然后选择功能区域中的 HTTPS代理抓包。根据弹出的提示按照配置文件和设置手机代理。如果是本机则会自动配置&#xff0c;只需要按照提醒操作即可。 iOS 抓包准备 通过 USB 将 iOS 设备连接到电脑&#xff0c;设备需解…

Java面试核心知识4

公平锁与非公平锁 公平锁&#xff08;Fair&#xff09; 加锁前检查是否有排队等待的线程&#xff0c;优先排队等待的线程&#xff0c;先来先得 非公平锁&#xff08;Nonfair&#xff09; 加锁时不考虑排队等待问题&#xff0c;直接尝试获取锁&#xff0c;获取不到自动到队尾…

在 Linux 下Ubuntu创建同权限用户

我是因为不小心把最开始创建的用户的文件夹颜色搞没了&#xff0c;再后来全白用习惯了&#xff0c;就不想卸载了&#xff0c;像创建一个和最开始创建的用户有一样的权限可以执行sudo -i进入root一样的用户 如图这是最原始的样子 第一步 创建新用户&#xff0c;我这里是因为之前…

Microsoft Sql Server 2019 函数理解

说到函数&#xff0c;首先和存储过程作个比较吧&#xff0c;两者有一个共同点都是预编译优化后存储在磁盘中&#xff0c;所以效率 要比T-SQL高一点点。值得注意的是&#xff0c;存储过程可以创建或访问临时表&#xff0c;而函数不可以&#xff1b; 同时函数不可 以修改表中的数…

依据正则表达式拦截文本

正则表达式匹配 因为我是go语言&#xff0c;所以展示golang的 包&#xff1a;"github.com/dlclark/regexp2" 更多欢迎访问&#xff1a;www.zpf0000.com // CanMatchRegexp return bool 某个字符串是否匹配正则表达式 func CanMatchRegexp(message string, regexpSt…

学习及笔记

1、计算md5 md5sum 文件名 2、跨服务器复制 scp 文件 目标用户名目标Ip:目标路径 3、curl curl -X POST http://10.105.2.46/getUerls -H "Content-Type: application/json" -d {"id": 379, "userId": "lyc", "password":…

【Unity插件】解决移动端UI安全区问题 - Safe Area Helper

在移动端设计界面时&#xff0c;必须要考虑的就是UI的安全区。 Unity本身也提供了Safearea的API。 但在asset store时已经有人提供了免费的插件&#xff08;Safe Area Helper&#xff09;&#xff0c;我们可以直接使用。 插件链接&#xff1a; https://assetstore.unity.com/p…

机器学习之随机森林算法实现和特征重要性排名可视化

随机森林算法实现和特征重要性排名可视化 目录 随机森林算法实现和特征重要性排名可视化1 随机森林算法1.1 概念1.2 主要特点1.3 优缺点1.4 步骤1.5 函数及参数1.5.1 函数导入1.5.2 参数 1.6 特征重要性排名 2 实际代码测试 1 随机森林算法 1.1 概念 是一种基于树模型的集成学…

OpenAI 故障复盘 - 阿里云容器服务与可观测产品如何保障大规模 K8s 集群稳定性

本文作者&#xff1a; 容器服务团队&#xff1a;刘佳旭、冯诗淳 可观测团队&#xff1a;竺夏栋、麻嘉豪、隋吉智 一、前言 Kubernetes(K8s)架构已经是当今 IT 架构的主流与事实标准&#xff08;CNCF Survey[1]&#xff09;。随着承接的业务规模越来越大&#xff0c;用户也在使…

面试:C++类成员初始化顺序

1、非静态数据成员&#xff1a;按它们在类定义的声明顺序初始化&#xff0c;不会按它们在初始化列表的顺序。 2、静态数据成员&#xff1a;在main函数启动之前&#xff0c;并且只初始化一次 3、基类构造函数&#xff1a;如果类从一个或多个基类继承而来&#xff0c;基类的构造…

Vue.js 使用插槽(Slots)优化组件结构

Vue.js 使用插槽&#xff08;Slots&#xff09;优化组件结构 今天我们聊聊 Vue.js 的一个超实用功能——插槽&#xff08;Slots&#xff09;。插槽是 Vue 组件开发中的神器&#xff0c;用好它&#xff0c;你可以让组件变得更灵活、更可复用&#xff0c;还能写出优雅的代码结构…

SpringBoot 使用 Cache 集成 Redis做缓存保姆教程

1. 项目背景 Spring Cache是Spring框架提供的一个缓存抽象层&#xff0c;它简化了缓存的使用和管理。Spring Cache默认使用服务器内存&#xff0c;并无法控制缓存时长&#xff0c;查找缓存中的数据比较麻烦。 因此Spring Cache支持将缓存数据集成到各种缓存中间件中。本文已常…