计算机
c base
c++ 基础 作用域及生命周期
c++ template
c++ 内存视角
c++ 函数指针
c++ 基础 基础语法
c++ 多线程
c++ 性能
c++ 类 基础
c++ 类 对象模型 类析构
c++ 类 设计模式
cmake
CMAKE环境搭建 windows
创建第一个cmakelists.txt
构建稍复杂的项目
动态链接库
EX1
EX1 START
EX1 ANSWER
EX2
EX2 START
EX2 ANSWER
EX3
EX3 START
EX3 ANSWER
变量
控制流程
函数和宏
查找和使用外部库
生成器表达式
qt 开发环境
qt c++
理解QObject 1
理解QObject 4
qt index
qt qml quick
qt ui
qt 多线程
数据结构 数组
PC问题监控及排查
PC程序性能优化
OS
TOOL
C++ STL
编程漫谈
C++实战-生产者 消费者流水线
C++实战 IO
本站点使用 MrDoc 构建
-
+
理解QObject 4
## 目录 1. [动态属性 (Dynamic Properties) [原片 @ 00:29](https://www.bilibili.com/video/BV1tm4y1s7fa?t=29)](https://www.bilibili.com/video/BV1xx4y1q7vD?t=29) 2. [事件处理 (Event Handling) [原片 @ 08:46](https://www.bilibili.com/video/BV1tm4y1s7fa?t=526)](https://www.bilibili.com/video/BV1xx4y1q7vD?t=526) 3. [事件过滤器 (Event Filter) [原片 @ 14:06](https://www.bilibili.com/video/BV1tm4y1s7fa?t=846)](https://www.bilibili.com/video/BV1xx4y1q7vD?t=846) 4. [对象查找与继承检查 (Object Lookup & Inheritance) [原片 @ 31:00](https://www.bilibili.com/video/BV1tm4y1s7fa?t=1860)](https://www.bilibili.com/video/BV1xx4y1q7vD?t=1860) 5. [AI 总结](#ai-summary) --- ## 动态属性 (Dynamic Properties) [原片 @ 00:29](https://www.bilibili.com/video/BV1tm4y1s7fa?t=29) ### 概念 * `QObject` 类引入了类似动态语言的“动态属性”概念,允许在运行时为对象添加和移除属性。 * 虽然 C++ 是静态编译型语言,结构体/类的成员在编译时确定,但 `QObject` 通过元对象系统扩展了这一限制。 * 这使得我们可以在不修改类定义的情况下,随时给对象增加额外的信息。 ### 关键 API 1. **设置属性 (`setProperty`)** * 函数原型: `bool setProperty(const char *name, const QVariant &value)` * 用法: `object->setProperty("PropertyName", value);` * 支持类型: `QVariant` 可以存储多种类型(整数、浮点数、字符串等)。如果传入的类型不匹配,QT 会尝试进行类型转换。 2. **获取属性名列表 (`dynamicPropertyNames`)** * 函数原型: `QList<QByteArray> dynamicPropertyNames() const` * 作用: 返回该对象当前所有已设置的动态属性的名称列表。 3. **获取属性值 (`property`)** * 函数原型: `QVariant property(const char *name) const` * 用法: `QVariant v = object->property("PropertyName");` * 提取数据: 获取到 `QVariant` 后,需要使用 `.toInt()`, `.toDouble()`, `.toString()` 等方法将其转换为具体类型。 4. **移除属性** * 可以通过将属性设置为特定的空值或不设置来移除(实际效果取决于具体实现,通常是不再引用或逻辑上忽略)。视频中演示了通过 `setProperty` 传空值或特定方式使其不在列表中显示。 --- ## 事件处理 (Event Handling) [原片 @ 08:46](https://www.bilibili.com/video/BV1tm4y1s7fa?t=526) ### `event(QEvent *event)` * 这是 `QObject` 接收和处理所有事件的入口虚函数。 * **返回值**: * `true`: 事件已被识别并处理。 * `false`: 事件未被处理。 * **重写策略**: * 如果子类重写了 `event` 函数,它必须先处理自己感兴趣的事件。 * 对于处理过的事件,直接返回 `true`,**不再调用父类的 `event`**。这意味着父类的默认处理将被跳过。 * 对于未处理或希望由父类处理的事件,最后必须调用 `return QObject::event(event);`(或父类的 `event`)。 * **事件分发**: * `QObject::event` 内部会根据 `event->type()` 将事件分发给具体的处理函数(如 `keyPressEvent`, `mousePressEvent` 等)。 * 如果在重写的 `event` 中拦截并处理了特定类型的事件,就不会再触发那些具体的处理函数。 --- ## 事件过滤器 (Event Filter) [原片 @ 14:06](https://www.bilibili.com/video/BV1tm4y1s7fa?t=846) ### 概念 * 允许一个对象拦截发送给另一个对象的事件。 * 常用于在不修改目标对象代码的情况下,监控或修改其行为。 ### 关键 API 1. **安装过滤器 (`installEventFilter`)** * 函数原型: `void installEventFilter(QObject *filterObj)` * 用法: `targetObject->installEventFilter(filterObject);` * 效果: `filterObject` 的 `eventFilter` 方法会在 `targetObject` 收到事件**之前**被调用。 2. **重写 `eventFilter`** * 函数原型: `virtual bool eventFilter(QObject *watched, QEvent *event)` * 参数: * `watched`: 被监控的目标对象。 * `event`: 即将发生的事件。 * 返回值: * `true`: 事件已被过滤(拦截),`watched` 对象将**收不到**此事件。 * `false`: 事件未被过滤,继续传递给 `watched` 对象的 `event` 函数处理。 ### 示例场景 * **禁止输入**: 在一个窗口中放置一个 `QTextEdit`。在主窗口中重写 `eventFilter`。 * 检测 `watched` 是否为 `QTextEdit`。 * 检测 `event->type()` 是否为 `QEvent::KeyPress`。 * 如果是,返回 `true`。结果:`QTextEdit` 无法接收键盘事件,导致无法输入文字。 * 如果不是,返回 `false`,让 `QTextEdit` 正常处理(如鼠标点击获取焦点等)。 ### 多个过滤器 * 如果一个对象安装了多个过滤器,调用顺序遵循 **LIFO (Last In First Out)**,即**后安装的过滤器先被调用**。 * 只要有一个过滤器返回 `true`,事件传递就会终止。 --- ## 对象查找与继承检查 (Object Lookup & Inheritance) [原片 @ 31:00](https://www.bilibili.com/video/BV1tm4y1s7fa?t=1860) ### `findChild` * 根据对象名查找子对象。 * **基本用法**: ```cpp // 默认递归查找所有后代 MyWidget *child = parent->findChild<MyWidget*>("ObjectName"); // 指定选项:只查找直接子对象 MyWidget *directChild = parent->findChild<MyWidget*>("ObjectName", Qt::FindDirectChildrenOnly); ``` * **参数说明**: * 第一个参数: 对象的名字 (String)。 * 第二个参数 (可选): `Qt::FindChildOptions`。 * `Qt::FindDirectChildrenOnly`: 仅查找直接子节点。 * (默认) 递归查找整个对象树。 * **注意**: 如果找不到,返回 `nullptr`。QT 对 `nullptr` 的操作进行了优化,不会崩溃,但需小心逻辑错误。 ### `findChildren` * 查找所有匹配的子对象,返回 `QList<T>`。 * 支持正则表达式匹配对象名。 ### `inherits` * 检查当前对象是否是指定类的实例或其子类。 * 用法: `obj->inherits("ClassName")` (注意这里传入的是类名的字符串)。 * 基于元对象系统,效率较高。 --- ## AI 总结 本视频深入讲解了 `QObject` 类的几个高级功能: 1. **动态属性**: 展示了如何在运行时像动态语言一样给 C++ 对象添加属性,通过 `setProperty` 和 `property` 进行读写。 2. **事件系统**: 详细解释了 `event` 函数的重写规则,强调了拦截事件时是否需要调用父类 `event` 的区别。 3. **事件过滤器**: 这是一个强大的机制,允许外部对象拦截目标对象的事件。通过 `installEventFilter` 安装,并在 `eventFilter` 中通过返回 `true` 来“吃掉”事件。还提到了多个过滤器的 LIFO 调用顺序。 4. **对象树操作**: 介绍了如何使用 `findChild` 和 `findChildren` 通过名字查找子对象,并区分了直接子对象和递归查找。最后简单提到了 `inherits` 用于类型检查。 这些功能是构建复杂 QT 应用的基础,特别是在需要自定义行为、监控子控件状态或管理对象层级关系时非常有用。
peipeo
2026年5月16日 17:10
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码