Qt源码分析: QChildEvent

本文记录QChildEvent事件相关代码分析。

注1:限于笔者研究水平,难免有表述不当,欢迎批评指正。

注2:博文会不定期更新,敬请关注。

一、QChildEvent的发送

分析QObject::setParent代码,当修改父对象时,便会旧parent发送QEvent::ChildRemoved事件;向新parent发送QEvent::ChildAdded事件。

/*!Makes the object a child of \a parent.\sa parent(), children()
*/
void QObject::setParent(QObject *parent)
{Q_D(QObject);Q_ASSERT(!d->isWidget);d->setParent_helper(parent);
}
void QObjectPrivate::setParent_helper(QObject *o)
{Q_Q(QObject);Q_ASSERT_X(q != o, Q_FUNC_INFO, "Cannot parent a QObject to itself");
#ifdef QT_DEBUGconst auto checkForParentChildLoops = qScopeGuard([&](){int depth = 0;auto p = parent;while (p) {if (++depth == CheckForParentChildLoopsWarnDepth) {qWarning("QObject %p (class: '%s', object name: '%s') may have a loop in its parent-child chain; ""this is undefined behavior",q, q->metaObject()->className(), qPrintable(q->objectName()));}p = p->parent();}});
#endifif (o == parent)return;if (parent) {QObjectPrivate *parentD = parent->d_func();if (parentD->isDeletingChildren && wasDeleted&& parentD->currentChildBeingDeleted == q) {// don't do anything since QObjectPrivate::deleteChildren() already// cleared our entry in parentD->children.} else {const int index = parentD->children.indexOf(q);if (parentD->isDeletingChildren) {parentD->children[index] = 0;} else {parentD->children.removeAt(index);if (sendChildEvents && parentD->receiveChildEvents) {QChildEvent e(QEvent::ChildRemoved, q);QCoreApplication::sendEvent(parent, &e);}}}}parent = o;if (parent) {// object hierarchies are constrained to a single threadif (threadData != parent->d_func()->threadData) {qWarning("QObject::setParent: Cannot set parent, new parent is in a different thread");parent = 0;return;}parent->d_func()->children.append(q);if(sendChildEvents && parent->d_func()->receiveChildEvents) {if (!isWidget) {QChildEvent e(QEvent::ChildAdded, q);QCoreApplication::sendEvent(parent, &e);}}}if (!wasDeleted && !isDeletingChildren && declarativeData && QAbstractDeclarativeData::parentChanged)QAbstractDeclarativeData::parentChanged(declarativeData, q, o);
}

因为QObject构造函数可以设置parent,此时发送QChildEvent事件,但对象并不一定创建完毕。

Refs. from QObject::childEvent(QChildEvent *)

QEvent::ChildAdded and QEvent::ChildRemoved events are sent to objects when children are added or removed. In both cases you can only rely on the child being a QObject, or if isWidgetType() returns true, a QWidget. (This is because, in the ChildAdded case, the child is not yet fully constructed, and in the ChildRemoved case it might have been destructed already).

二、应用案例

在SALOME中,SUIT_Desktop通过响应QChildEvent消息来讲SUIT_ViewWindow添加到SUIT_Desktop中。

class SUIT_Desktop::ReparentEvent : public QEvent
{
public:ReparentEvent( Type t, QObject* obj ) : QEvent( t ), myObj( obj ) {};QObject* object() const { return myObj; }private:QPointer<QObject> myObj;
};
/*!Child event.
*/
void SUIT_Desktop::childEvent( QChildEvent* e )
{if ( e->type() == QEvent::ChildAdded && e->child()->isWidgetType() ) {// The following line is a workaround to avoid showing view window as a top-level window// before re-parenting it to workstack (issue #23467).// See SUIT_ViewWindow::setVisible() and SUIT_Desktop::customEvent().e->child()->setProperty("blockShow", true );QApplication::postEvent( this, new ReparentEvent( QEvent::Type( Reparent ), e->child() ) );}else {QtxMainWindow::childEvent( e );}
}void SUIT_Desktop::customEvent( QEvent* e )
{if ( (int)e->type() != Reparent )return;ReparentEvent* re = (ReparentEvent*)e;SUIT_ViewWindow* wid = ::qobject_cast<SUIT_ViewWindow*>( re->object() );if ( wid ){bool invis = wid->testAttribute( Qt::WA_WState_ExplicitShowHide ) &&wid->testAttribute( Qt::WA_WState_Hidden );// The following line is a workaround to avoid showing view window as a top-level window// before re-parenting it to workstack (issue #23467).// See SUIT_ViewWindow::setVisible() and SUIT_Desktop::childEvent().wid->setProperty("blockShow", false);addWindow( wid );wid->setVisible( !invis );}
}

Refs. from QObject::customEvent(QEvent *event) 

This event handler can be reimplemented in a subclass to receive custom events. Custom events are user-defined events with a type value at least as large as the QEvent::User item of the QEvent::Type enum, and is typically a QEvent subclass. The event is passed in the event parameter. 

/*! Constructor.*/
SUIT_ViewWindow::SUIT_ViewWindow( SUIT_Desktop* theDesktop ): QMainWindow( theDesktop ), myManager( 0 ), myIsDropDown( true ), mySyncAction( 0 )
{myDesktop = theDesktop;setWindowIcon( myDesktop ? myDesktop->windowIcon() : QApplication::windowIcon() );setAttribute( Qt::WA_DeleteOnClose );myToolMgr = new QtxActionToolMgr( this );setProperty( "VectorsMode", false );
}

网络

QChildEventhttps://doc.qt.io/qt-6/qchildevent.html

QObject::childEvent(QChildEvent* event)https://doc.qt.io/qt-6/qobject.html#childEvent

QObject::customEvent(QEvent *event)https://doc.qt.io/qt-6/qobject.html#customEvent

SALOME源码分析:GUI模块https://blog.csdn.net/qq_26221775/article/details/127759145?spm=1001.2014.3001.5502

SALOME源码分析: GUI模块主要组件https://blog.csdn.net/qq_26221775/article/details/148845050?spm=1001.2014.3001.5502

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

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

相关文章

《Whisper :说明书 》

[论文] [模型卡] [Colab 示例] Whisper 是一种通用的语音识别模型。它基于各种音频的大型数据集进行训练&#xff0c;也是一种多任务模型&#xff0c;可以执行多语言语音识别、语音翻译和语言识别。 方法 Transformer 序列到序列模型针对各种语音处理任务进行训练&#xff0c;…

回溯----8.N皇后

题目链接 /** 将n个棋子放在n*n的棋盘上,不同列,不同行,不同斜线 大致执行流程: 首先选取第一行第一格放置第一个棋子,再从第二行第一个位置开始选取合法的位置(不同行不同列不同斜线)放置棋子,重复上述流程迭代行数, 直到放置n个棋子。 若放置途中出现无合法位置的情况,回溯将…

微机电子拉伸试验机

对于不同材料的试样&#xff0c;由于其化学成分及组织的不同&#xff0c;在拉伸过程中会体现 出不同的物理现象及力学性质。西安力创&#xff08;LETRY&#xff09;公司专业制造WDL/WDW系列微机控制电子万能试验机&#xff0c;主要适用于金属板材、棒材、管材、金属丝、金属箔、…

【数据结构与算法】数据结构核心概念系统梳理

第一章 绪论:基础概念体系 🚩算法:问题求解步骤的描述。 🚩非递归的算法效率更高。 1.1 逻辑结构 vs 存储结构 维度逻辑结构存储结构(物理结构)定义数据元素之间的逻辑关系数据结构在计算机中的实现方式分类线性/树形/图/集合顺序/链式/索引/散列独立性独立于存储结构…

73页PPT | 大数据平台规划与数据价值挖掘应用咨询项目解决方案

推荐摘要&#xff1a;在数字化浪潮中&#xff0c;企业数据量呈几何级增长&#xff0c;却常因缺乏科学规划的大数据平台&#xff0c;陷入数据孤岛、处理效率低下的困境&#xff0c;难以充分挖掘数据价值。特推出大数据平台规划与数据价值挖掘应用咨询项目解决方案&#xff0c;正…

gRPC 与 Protobuf 的深度集成 —— 从服务定义到多语言交互(Go + Java 示例)

在前几篇文章中&#xff0c;我们已经掌握了 Protobuf 的基础语法、高级特性和序列化反序列化操作。本篇文章将深入讲解 gRPC 与 Protobuf 的集成&#xff0c;重点介绍如何通过 .proto 文件定义服务接口&#xff0c;并在 Go 和 Java 中实现 gRPC 服务与客户端的完整交互流程。我…

可信计算的基石:TPM技术深度解析与应用实践

可信计算的基石&#xff1a;TPM技术深度解析与应用实践 引言&#xff1a;数字世界的"信任之锚" 在数据泄露事件频发的时代&#xff0c;传统软件级安全防护已力不从心。TPM&#xff08;可信平台模块&#xff09;作为硬件级安全解决方案&#xff0c;正成为现代计算设…

「ECG信号处理——(18)基于时空特征的心率变异性分析」2025年6月23日

一、HRV概述 心率变异性&#xff08;Heart rate variability ,HRV&#xff09;分析是通过测量分析连续正常R-R间期的时间变化来反映心率的变化程度的&#xff0c;根据计算RR 序列的统计指标&#xff0c;或者是画出RR间期的直方图和散点图来反映HRV的大小情况。下面我们从男性与…

【学习笔记】深入理解Java虚拟机学习笔记——第10章 前端编译与优化

第10章 前端编译与优化 10.1 概述 1>前端编译器&#xff1a;Javac命令。 【.java文件->.class文件】 2>即时编译器&#xff1a;Hotspot.C1.C2 【.class文件->机器码】 3>提前编译器&#xff1a;JDK的Jaotc等【.java->机器码】 10.2 Javac 编译器 10.2.1 …

Python 区块链与Web3开发指南

https://www.python.org/static/community_logos/python-logo-master-v3-TM.png 区块链基础概念 区块链核心特性 python 复制 下载 class Block:def __init__(self, index, timestamp, data, previous_hash):self.index indexself.timestamp timestampself.data datas…

工业智能体调参闭环:从物料感知到智慧工艺的落地路径

用户定义目标&#xff1a;智能工艺的起点不是机器&#xff0c;而是人 在智能制造系统中&#xff0c;工艺调优的第一步并非直接依赖AI或自动化设备&#xff0c;而是始于用户的明确输入。用户需要在系统中定义产品的工艺要求&#xff0c;包括目标尺寸与规格&#xff08;如长宽高…

【Linux学习笔记】进程间通信之共享内存

【Linux学习笔记】进程间通信之共享内存 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;Linux学习笔记 文章目录 【Linux学习笔记】进程间通信之共享内存前言一. system V共享内存1.1 共享内存数据结构1.2 共享内存函数1.3 共享内存实现通信…

郭碧婷闯入女团赛道 与刘忻张予曦蔡诗芸组成ROLLING SISTERS

近日&#xff0c;郭碧婷与刘忻、张予曦、蔡诗芸组成的女团ROLLING SISTERS正式官宣&#xff0c;并发布《Rolling Life》《Alpha》两首单曲&#xff01; 此次几位姐姐的组合让大家眼前一亮&#xff0c;尤其是郭碧婷造型颠覆以往。银灰色挑染短发搭配棱角分明的黑色烟熏妆&#x…

2025再升级:医疗数智立体化体系V2.0架构简介

在医疗数智立体化体系第一版基础上,融入量子物理的第一性原理计算、人工智能(AI)、高性能云计算(HPC)和标准化机器人自动化整合成“医疗数智立体化体系2.0”,代表了医疗研发未来的重要发展方向。这个体系的核心在于深度融合物理世界规律、智能计算与自动化执行,为医疗AI…

Day40 训练和测试的规范写法

目录 一、彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中 单通道图片的规范写法 彩色图片的规范写法 二、展平操作&#xff1a;除第一个维度batchsize外全部展平 图像任务中的张量形状 NLP任务中的张量形状 1. Flatten操作 2. view/reshape操作 总结 三…

Linux 文件 I/O 与标准 I/O 缓冲机制详解

一、什么是标准 I/O&#xff1f;&#xff08;FILE* 接口&#xff09; 标准 I/O 是 C 标准库为我们提供的一套高级文件操作接口&#xff0c;核心基于结构体 FILE&#xff0c;常见函数如&#xff1a; fopen() / fclose() fread() / fwrite() fprintf() / fscanf() fflush() /…

C++的前世今生-C++11

C98&#xff08;ISO/IEC 14882:1998&#xff09; C98 是 C 的第一个标准化版本&#xff08;ISO/IEC 14882:1998&#xff09;&#xff0c;它正式确立了 C 的核心语言特性和标准库。以下是 C98 的主要特性总结&#xff1a; 一、核心语言特性** 模板&#xff08;Templates&…

词编码模型怎么进行训练的,输出输入是什么,标签是什么

词编码模型怎么进行训练的,输出输入是什么,标签是什么 词编码模型的训练本质是通过数据驱动的方式,将离散的文本符号映射为连续的语义向量。 一、训练机制:从符号到向量的映射逻辑 1. 核心目标 将单词/子词(Token)映射为低维向量,使语义相关的词在向量空间中距离更近…

【Linux指南】文件管理高级操作(复制、移动、查找)

引言 在Linux系统管理中&#xff0c;文件的复制、移动与查找是比基础操作更进阶的核心技能&#xff0c;它们构成了高效管理文件系统的"三驾马车"。当我们需要备份重要数据、重构目录结构或在庞大的文件系统中定位目标文件时&#xff0c;cp、mv、find等命令将成为最得…

【栈】-----【小C的记事本】

小C的记事本 题目描述 小C最近学会了 Java 小程序的开发&#xff0c;他很开心&#xff0c;于是想做一个简单的记事本程序练练手。 他希望他的记事本包含以下功能&#xff1a; append(str)&#xff1a;向记事本插入字符串 str&#xff08;英文字符&#xff09;。delete(k)&am…