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

简介: 欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资

头图

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

[toc]

关键字: 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

image-20230801225943282

声明属性的要求

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

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使用。(我使用的是经典的那种)

    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 属性系统有了新的理解,咱们再开一篇。这篇先这样


博客签名2021

相关文章
|
5月前
|
设计模式 缓存 编译器
【C++ 元对象系统03】深入探索Qt反射:从原理到实践
【C++ 元对象系统03】深入探索Qt反射:从原理到实践
243 4
|
5月前
|
开发框架 Java 编译器
【Qt 元对象系统 01 】深入探索Qt的元对象系统:核心地位、功能与构成
【Qt 元对象系统 01 】深入探索Qt的元对象系统:核心地位、功能与构成
166 1
|
5月前
|
算法 编译器 Linux
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
107 0
|
5月前
|
缓存 编译器 程序员
【Qt 元对象系统04】 深入浅出Qt的QMetaObject:探索元对象的魔法
【Qt 元对象系统04】 深入浅出Qt的QMetaObject:探索元对象的魔法
334 0
|
5月前
|
安全 数据处理 C++
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
1116 3
|
2月前
|
存储 C++
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
|
2月前
|
API
Qt绘图之Paint系统
Qt绘图之Paint系统
41 2
|
2月前
|
开发者
【Qt 学习笔记】Qt系统相关 | Qt事件 | 事件的介绍及基本概念
【Qt 学习笔记】Qt系统相关 | Qt事件 | 事件的介绍及基本概念
149 4
|
2月前
从源码角度分析Qt元对象系统2
从源码角度分析Qt元对象系统
44 0
|
2月前
|
存储
从源码角度分析Qt元对象系统1
从源码角度分析Qt元对象系统
57 0
下一篇
无影云桌面