欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 明星 > QT学习十九天 QT核心机制

QT学习十九天 QT核心机制

2025/2/25 11:51:28 来源:https://blog.csdn.net/qq_15409121/article/details/144980337  浏览:    关键词: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 对象。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词