当前位置: 首页 > article >正文

QT学习十九天 QT核心机制

QT学习十九天 QT核心机制

  • 核心机制简介
    • 对象模型
    • 元对象系统
    • 属性系统
    • 对象树与拥有权

核心机制简介

除了信号和槽,QT中还有对象模型、元对象系统、属性系统、对象树于拥有权等,他们是构成QT的基础。

对象模型

标准 C++ 对象模型可以在运行时非常有效的支持对象范式(object paradigm),但是它的静态特性在一些问题上不够灵活。图形用户界面编程不仅需要运行时的高效性,还需要高度的灵活性。为此,Qt 在标准 C++ 对象模型的基础上添加了一些特性,形成了自己的对象模型。

  • 一个强大的无缝对象通信机制----信号和槽
  • 可查询、可设计的对象属性系统
  • 强大的事件和事件过滤器
  • 基于上下文的国际化字符串翻译机制
  • 完善的定时器驱动,可以在一个事件驱动GUI中处理多个任务
  • 分层结构的、可查询的对象树,它使用一种很自然的方式来组织对象拥有权
  • 守卫指针即 QPointer,它在引用对象被销毁时自动将其设置为 0
  • 动态的对象转换机制
  • 支持创建自定义类型

Qt 的这些特性大多是在遵循标准 C++ 规范内实现的,使用这些特性都必须要继承自 QObject 类。其中,对象通信机制和动态属性系统还需要元对象系统的支持。

元对象系统

Qt 中的元对象系统是对 C++ 的扩展,使其更适合真正的组件图形用户界面编程,提供了对象间通信的信号和槽机制、运行时类型信息和动态属性系统。元对象系统是基于以下3个条件的。

  • 该类必须继承自 QObject 类
  • 必须在类定义的私有部分添加 Q_OBJECT 宏
  • 元对象编译器 Meta-Object Compiler(MOC)为 QObject 的子类实现元对象特性提供必要条件的代码。

其中 MOC 工具读取一个 C++ 源文件,如果它发现一个或者多个类定义中包含有 Q_OBJECT 宏,便会另外创建一个 C++ 源文件,其中包含了为每一个类生成的元对象代码。这些产生的源文件或者被包含进类的源文件中,或者和类的实现同时进行编译和链接。

元对象系统主要是为了实现信号和槽机制才被引入的,不过除了信号和槽机制,元对象系统还提供了其他一些特性。

  • QObject::metaObject() 返回一个类的元对象 QMetaObject
  • QMetaObject::className() 可以在运行时以字符串形式返回类名,而不需要 C++ 编辑器原生的运行时类型信息的支持。
  • QObject::inherits() 返回一个对象是否是 QObject 继承树上一个类的实例的信息
  • QObject::tr() 进行字符串翻译实现国际化
  • QObject::setProperty() 和 QObject::property() 通过名字来动态设置或者获取对象属性
  • QMetaObject::newInstance() 构造类的一个新实例
  • qobject_cast() 对 QObject 类进行动态类型转换,这个函数的功能类似于标准 C++ 中的 dynamic_cast()

属性系统

Qt 提供了强大的基于元对象系统的属性系统,可以在运行 Qt 的平台上支持标准 C++ 编译器。要在一个类中声明属性,该类必须继承自 QObject 类,还要在声明前使用 Q_PROPERTY() 宏

class Rectangle : public QObject {
    Q_OBJECT
public:
    Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged BINDABLE bindableWidth)
    Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged BINDABLE bindableHeight)

    Rectangle(QObject *parent = nullptr) : QObject(parent), m_width(0), m_height(0) {
        m_height.setBinding([this]() { return m_width; });
    }

    int width() const { return m_width; }
    void setWidth(int w) {
        if (m_width == w) return;
        m_width = w;
        emit widthChanged();
    }

    int height() const { return m_height; }
    void setHeight(int h) {
        if (m_height == h) return;
        m_height = h;
        emit heightChanged();
    }

signals:
    void widthChanged();
    void heightChanged();

private:
    Q_OBJECT_BINDABLE_PROPERTY(Rectangle, int, m_width, &Rectangle::widthChanged);
    Q_OBJECT_BINDABLE_PROPERTY(Rectangle, int, m_height, &Rectangle::heightChanged);
};

这个例子中,首先使用Q_PROPERTY宏声明了width和height两个可绑定属性,并分别为它们指定了读取器(READ)、写入器(WRITE)以及变更通知信号(NOTIFY)。接着,在构造函数内部调用了setBinding()方法,建立了从width到height的单向数据流。每当width发生改变时,height也会随之调整至相同的数值。最后,通过定义私有成员变量m_width和m_height及其对应的绑定属性,实现了对属性值的有效管理和跟踪。

对象树与拥有权

对象树用来管理所有的 QObject 类及其子类的对象。当创建一个 QObject 对象时,子对象会出现在父对象的 children() 列表中。如果父对象被销毁,子对象也会随之被销毁。这个机制很适合管理 GUI 对象。


http://www.kler.cn/a/471912.html

相关文章:

  • 大模型LLM-Prompt-CRISPE
  • 关于Mac使用VSCode连接虚拟机
  • 5.1 数据库:INSERT 插入语句
  • 汇编实现函数调用
  • PDFMathTranslate: Star13.8k,一款基于AI的PDF文档全文双语翻译PDF文档全文双语翻译,保留格式神器,你应该需要它
  • Python递归(汉诺塔问题)
  • WebRtc02: WebRtc架构、目录结构、运行机制
  • Lianwei 安全周报|2024.1.7
  • 【Java】JVM内存相关笔记
  • 代理IP授权机制:保障安全与效率的双重考量
  • matlab专栏-常见问题处理
  • 青少年编程与数学 02-006 前端开发框架VUE 12课题、表单绑定
  • C#高级:递归4-根据一颗树递归生成数据列表
  • 通过 ulimit 和 sysctl 调整Linux系统性能
  • ThinkPHP 8高效构建Web应用-获取请求对象
  • VUE条件树查询 自定义条件节点
  • 【JMeter】配置元件Config Element
  • 浅谈棋牌游戏开发流程四:核心业务逻辑(二)——房间匹配与对局流程
  • Java 日期时间格式化标准
  • 【HarmonyOS NEXT】鸿蒙应用实现屏幕录制详解和源码
  • 1.07 标准IO
  • 数据结构:LinkedList与链表—无头双向链表(二)
  • STM32 拓展 电源控制
  • 大数据架构设计:数据分层治理的全景指南
  • 人机交互复习笔记
  • ECharts系列:echart中折线图折线设置不平滑显示