035-第三代软件开发-Qt属性系统

第三代软件开发-Qt属性系统

文章目录

关键字: QtQmlQ_PROPERTY setProperty属性

项目介绍

欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。

在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。

在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资源消耗,以确保我们的项目在各种平台和设备上都能够高效运行。

无论您是对 QML 和 C++ 开发感兴趣,还是需要我们为您构建复杂的用户界面和后端逻辑,我们都随时准备为您提供支持。请随时联系我们,让我们一同打造现代化、高性能的 QML & C++ 项目!

重要说明☝

☀该专栏在第三代软开发更新完将涨价

Qt属性系统

其实Qt 属性系统 我也是第一次在项目中大量的成系统的使用,要说元对象系统,那我们都是知道是Qt的根基,但是这个Qt 属性系统我也不知道该如何形容,我用下的感觉总结就是如果是纯QWidget系列代码,那不如不用,如果是和Qml一起使用,真香。

Qt 的属性系统是一种机制,用于在 Qt 对象中定义、访问和管理属性。它提供了一种方便的方式来定义对象的属性,并允许通过属性名称进行访问、修改和监视。

以下是 Qt 属性系统的详细介绍:

  1. 属性(Properties):

    • 属性是 Qt 对象的特征或状态,可以是任何数据类型,例如整数、字符串等。
    • 属性可以通过 Q_PROPERTY 宏在类的头文件中进行定义。
  2. 访问器函数(Accessor Functions):

    • 对于每个属性,Qt 提供了自动生成的访问器函数,用于获取和设置属性的值。
    • 访问器函数遵循命名约定:propertyName() 用于获取属性值,setPropertyName(value) 用于设置属性值。
  3. 反射(Reflection):

    • Qt 属性系统基于反射机制,允许在运行时获取和操作对象的属性信息。
    • 可以使用 QObject::metaObject() 函数获取对象的元对象(QMetaObject),然后使用元对象的方法来访问属性。
  4. 元对象系统(Meta-Object System):

    • 元对象系统是 Qt 的核心部分,用于支持属性系统、信号与槽等功能。
    • QMetaObject 是一个描述对象的结构和行为的元对象,包括属性、方法、信号和槽等。
  5. 动态属性(Dynamic Properties):

    • Qt 的属性系统还支持动态属性,允许在运行时为对象添加新的属性。
    • 可以使用 QObject::setProperty(propertyName, value) 方法来设置动态属性,使用 QObject::property(propertyName) 方法来获取动态属性值。
  6. 信号与槽(Signals and Slots):

    • 属性系统与信号与槽机制密切相关。当属性的值发生变化时,可以使用信号和槽来通知其他部分进行相应的处理。
    • 可以通过属性的 notify 信号来触发属性值变化的通知。

总结:Qt 的属性系统提供了一种方便而强大的方式来管理对象的属性。它支持静态属性和动态属性,并与元对象系统、反射和信号与槽机制紧密集成,使得开发者可以轻松地定义、访问和操作对象的属性。

目的

最近越写越迷茫了,就Qt 的属性系统而言,目前仅仅是会用,但是真的很想知道当初Qt 设计这个东西的初衷是什么,是为了C++与 Qml 交互的方便吗?带着这个问题找了百度,也找了Google,终究大家都是清一色如何使用,却没有一个人说说的他的由来,所以以下是GPT 给出的答案

问:开发 Qt 属性系统的目的是什么

答:Qt 属性系统的目的是为了提供一种方便和灵活地管理对象属性的方式。它允许开发人员在 Qt 应用程序中定义和操作对象的属性,包括读取、写入、通知、验证以及与其他属性之间建立关联等操作。

以下是开发 Qt 属性系统的一些主要目的:

  1. 简化属性管理:Qt 属性系统使开发人员能够以一致的方式管理对象的属性。通过使用属性系统,可以将属性的读取、写入和通知功能集成到对象中,而不需要手动编写大量的代码。

  2. 支持元对象系统:属性系统与 Qt 的元对象系统紧密集成。这意味着属性可以在运行时通过名称进行访问,并且支持信号和槽机制。

  3. 可扩展性:Qt 属性系统是可扩展的,开发人员可以根据自己的需求定义自定义属性类型。这使得开发人员能够创建适合特定应用程序需求的灵活的属性。

  4. 与界面框架的集成:Qt 属性系统与 Qt 的界面框架(如 Qt Widgets 和 Qt Quick)无缝集成。这意味着可以轻松地将属性与用户界面元素绑定,实现属性值的即时更新和交互。

总的来说,Qt 属性系统旨在提供一种简单、灵活和可扩展的方式来管理对象的属性,从而帮助开发人员更高效地构建 Qt 应用程序。

属性与类成员

我特意去帮助文档搜索了Q_PROPERTY,它是这么描述的

This macro is used for declaring properties in classes that inherit QObject. Properties behave like class data members, but they have additional features accessible through the Meta-Object System.

该宏用于声明继承 QObject 的类中的属性。 属性的行为类似于类数据成员,但它们具有可通过元对象系统访问的附加功能。

所以我理解看来,我可以把属性当做类成员,但是不能类成员当做属性。是可以这么理解吧。

使用

这个就是网上清一色的内容,这里咱们搬运一下大佬一去、二三里的博客内容

https://blog.csdn.net/liang19890820/article/details/52022714

声明属性的要求

要声明一个属性,在继承QObject的类中使用Q_PROPERTY()宏。

C++ 复制代码
Q_PROPERTY(type name
           (READ getFunction [WRITE setFunction] |
            MEMBER memberName [(READ getFunction | WRITE setFunction)])
           [RESET resetFunction]
           [NOTIFY notifySignal]
           [REVISION int]
           [DESIGNABLE bool]
           [SCRIPTABLE bool]
           [STORED bool]
           [USER bool]
           [CONSTANT]
           [FINAL])

下面的示例,展示了如何使用MEMBER关键字将类成员变量导出为Qt属性。注意:NOTIFY信号必须被指定,这样才能被QML使用。(我使用的是经典的那种)

C++ 复制代码
    Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)
    Q_PROPERTY(qreal spacing MEMBER m_spacing NOTIFY spacingChanged)
    Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)
    ...
signals:
    void colorChanged();
    void spacingChanged();
    void textChanged(const QString &newText);

private:
    QColor  m_color;
    qreal   m_spacing;
    QString m_text;

一个属性的行为就像一个类的数据成员,但它有通过元对象系统访问的附加功能。

如果MEMBER关键字没有被指定,则一个READ访问函数是必须的。它被用来读取属性值。理想的情况下,一个const函数用于此目的,并且它必须返回的是属性类型或const引用。比如:QWidget::focus是一个只读属性,通过READ函数QWidget::hasFocus()访问。

一个WRITE访问函数是可选的,用于设置属性的值。它必须返回void并且只能接受一个参数,属性的类型是类型指针或引用,例如:QWidget::enabled具有WRITE函数QWidget::setEnabled()。只读属性不需要WRITE函数,例如:QWidget::focus没有WRITE函数。

如果READ访问函数没有被指定,则MEMBER变量关联是必须的。这使得给定的成员变量可读和可写,而不需要创建READ和WRITE访问函数。如果需要控制变量访问,仍然可以使用READ和WRITE函数而不仅仅是MEMBER(但别同时使用)。

一个RESET函数是可选的,用于将属性设置为上下文指定的默认值。例如:QWidget::cursor有READ和WRITE函数QWidget::cursor()和QWidget::setCursor(),同时也有一个RESET函数QWidget::unsetCursor(),因为没有可用的QWidget::setCursor()调用可以确定的将cursor属性重置为上下文默认的值。RESET函数必须返回void类型,并且不带任何参数。

一个NOTIFY信号是可选的。如果定义了NOTIFY,则需要在类中指定一个已存在的信号,该信号在属性值发生改变时发射。与MEMBER变量相关的NOTIFY信号必须有零个或一个参数,而且必须与属性的类型相同。参数保存的是属性的新值。NOTIFY信号应该仅当属性值真正的发生变化时发射,以避免被QML重新评估。例如:当需要一个没有显式setter的MEMBER属性时,Qt会自动发射信号。

一个REVISION数字是可选的。如果包含了该关键字,它定义了属性并且通知信号被特定版本的API使用(通常是QML);如果没有包含,它默认为0。

DESIGNABLE属性指定了该属性在GUI设计器(例如:Qt Designer)里的编辑器中是否可见。大多数的属性是DESIGNABLE (默认为true)。除了true或false,你还可以指定boolean成员函数。

SCRIPTABLE属性表明这个属性是否可以被一个脚本引擎操作(默认是true)。除了true或false,你还可以指定boolean成员函数。

STORED属性表明了该属性是否是独立存在的还是依赖于其它属性。它也表明在保存对象状态时,是否必须保存此属性的值。大多数属性是STORED(默认为true)。但是例如:QWidget::minmunWidth()的STROED为false,因为它的值从QWidget::minimumSize()(类型为QSize)中的width部分取得。

USER属性指定了属性是否被设计为用户可见和可编辑的。通常情况下,每一个类只有一个USER属性(默认为false)。例如: QAbstractButton::checked是(checkable)buttons的用户可修改属性。注意:QItemDelegate获取和设置widget的USER属性。

CONSTANT属性的出现表明属性是一个常量值。对于给定的object实例,常量属性的READ函数在每次被调用时必须返回相同的值。对于不同的object实例该常量值可能会不同。一个常量属性不能具有WRITE函数或NOYIFY信号。

FINAL属性的出现表明属性不能被派生类所重写。有些情况下,这可以用于效率优化,但不能被moc强制执行。必须注意不能覆盖一个FINAL属性。

动态属性

这部分我还没有实际使用到,或者是没有大量使用,没有啥感觉,我们还是搬运一下大佬的内容,以及是上方链接

QObject::setProperty()也可以用来在运行时期向一个类的实例添加新的属性。当使用一个名字和值调用它时,如果QObject中一个指定名称的属性已经存在,并且如果给定的值与属性的类型兼容,那么,值就被存储到属性中,然后返回true。如果值与属性类型不兼容,属性的值就不会发生改变,会返回false。但是如果QObject中一个指定名称的属性不存在(例如:未用Q_PROPERTY()声明),一个带有指定名称和值的新属性就被自动添加到QObject中,但是依然会返回false。这意味着返回值不能用于确定一个属性是否被设置值,除非事先知道这个属性已经存在于QObject中。

注意:态属性被添加到每一个实例中,即:它们被添加到QObject中,而不是QMetaObject。一个属性可以从一个实例中删除,通过传入属性名和非法的QVariant值给QObject::setProperty()。默认的QVariant构造器会构造一个非法的QVariant。

动态属性可用QObject::property()来查询,就像使用Q_PROPERTY()声明的属性一样。

属性和自定义类型

被属性使用的自定义类型需要使用Q_DECLARE_METATYPE()宏注册,以便它们的值能被保存在QVariant对象中。这使得它们适用于在类定义时使用Q_PROPERTY()宏声明的静态属性,以及运行时创建的动态属性。

总结一下

额 说实话,目前还是云里雾里的,目前我能力也只能到这个地步,后期如果对Qt 属性系统有了新的理解,咱们再开一篇。这篇先这样


相关推荐
用户805533698036 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner6 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz11 天前
QML Hello World 入门示例
qt
xcyxiner14 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner14 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner15 天前
DicomViewer (添加模型类)3
qt
xcyxiner15 天前
DicomViewer (目录调整) 2
qt
xcyxiner15 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能17 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G17 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt