Qt的静态属性和动态属性

在这里插入图片描述
1. 静态属性(Static Properties)
1.1 基本概念
静态属性是指编译时候就已经确定的属性,通常是通过Q_PROPERTY宏声明。运行时可以通过元对象系统访问和操作。
1.2 使用方法
声明静态属性:

class MyClass : public QObject {
    Q_OBJECT
    Q_PROPERTY(int myProperty READ myProperty WRITE setMyProperty NOTIFY myPropertyChanged)
     /*int 属性类型
     * myProperty 属性名
     * READ 读
     * myProperty 读方法
     * WRITE 可选
     * setMyProperty 设置属性的方法,可选
     * NOTIFY 可选 后面跟这个中已经定义好的一个信号函数,调用setMyProperty的时候,在这个函数中,当这个属性的值发生改变就手动会发出这个信号。
     * 这个信号函数必须采用零个或者一个参数,这个参数必须和属性的类型一致
     * myPropertyChanged可选 指定的信号
     */
public:
    MyClass(QObject *parent = nullptr) : QObject(parent), m_myProperty(0) {}
    int myProperty() const { return m_myProperty; }
    void setMyProperty(int value) {
        if (m_myProperty != value) {
            m_myProperty = value;
            emit myPropertyChanged();
        }
    }
signals:
    void myPropertyChanged();
private:
    int m_myProperty;
};

访问静态属性:
方式1:通过元对象访问:metaObject->property() metaObject->propertyOffset()
方式2:直接通过Q_PROPERTY声明的get/set方法访问

//测试静态属性
void demoStaticProperty()
{
    Property proper;
    //通过 set方法设置属性
    proper.setGender(Property::Female);
    qDebug()<<"访问方式1 Gender:"<<proper.gender();

//    访问元信息
//     元对象系统:通过metaObject访问属性的元信息,包括属性名称、类型和值。
//    遍历属性:使用QMetaObject::propertyCount 和 QMetaObject::property
//    遍历所有属性,并打印其名称、类型和值
    const QMetaObject *metaObject = proper.metaObject();
    int start = metaObject->propertyOffset();//获取用户定义属性的起始索引
    for (int i = start; i < metaObject->propertyCount(); ++i)
    {
        QMetaProperty metaProperty = metaObject->property(i);
        qDebug() << "访问方式2 Property Name:" << metaProperty.name();
        qDebug() << "Property Type:" << metaProperty.typeName();
        qDebug() << "Property Value:" << metaProperty.read(&proper);
    }
    qDebug()<<"访问方式3 gender:"<<proper.property("gender").toInt();
    //通过属性名设置值
    proper.setProperty("gender",Property::Other);
    qDebug()<<"NEW gender:"<<proper.gender();
}

1.3 应用场景
数据绑定:静态属性可以与Qt的信号和槽机制结合,实现数据绑定。
数据绑定通常是指将一个数据源(如一个变量的值)与一个或者多个用户界面元素(如控件的属性)绑起来,当数据源发生变化的术后,用户界面元素的属性会自动更新。

样式表定制:静态属性可以用于样式表中,根据属性值应用不同的样式。

  this->setProperty("customstyle",true);//设置静态属性
 //应用样式表 使用样式表setStyleSheet根据customStyle属性的值应用不同的样式。
  setStyleSheet("StaticProperty[customstyle=true] { background-color: red; }");

元信息访问:通过元对象系统访问属性的元信息,如类型、名称等。

    // 访问元信息
    /*元对象系统:通过metaObject访问属性的元信息,包括属性名称、类型和值。
    遍历属性:使用QMetaObject::propertyCount 和 QMetaObject::property
    遍历所有属性,并打印其名称、类型和值。*/
    const QMetaObject *metaObject = widget.metaObject();
    for (int i = 0; i < metaObject->propertyCount(); ++i) {
        QMetaProperty metaProperty = metaObject->property(i);
        qDebug() << "Property Name:" << metaProperty.name();
        qDebug() << "Property Type:" << metaProperty.typeName();
        qDebug() << "Property Value:" << metaProperty.read(&widget);
    }

1.4 注意事项
静态属性需要在类中声明,并且需要提供读取和写入方法。
静态属性支持信号通知,当属性值改变时可以发出信号。

2. 动态属性(Dynamic Properties)
2.1 基本概念
动态属性是运行时动态添加到对象的属性。
它们不需要在类定义中声明,可以动态地添加、修改和删除。

2.2 使用方法
设置动态属性:

//setProperty(const QString &name,const QVariant &value)             
obj.setProperty("dynamicProperty", "value");

获取动态属性:

//property(const QString &name)const
qDebug() << obj.property("dynamicProperty").toString();

检查动态属性是否存在:

if (obj.dynamicPropertyNames().contains("dynamicProperty")) {
    qDebug() << "Dynamic property exists.";
}

2.3 应用场景
运行时扩展对象属性:动态属性适合在运行时根据需要添加属性。
样式表QSS使用自定义属性:动态属性可以用于样式表中,根据属性值应用不同的样式。
临时存储与对象相关的数据:动态属性可用于管理对象的运行时状态。

2.4 注意事项
动态属性的值是QVariant类型,需要确保类型正确性。
动态属性的性能开销比静态属性略高,因为它涉及到运行时的查找。

3. 静态属性与动态属性的区别

静态属性动态属性
编译时(通过宏声明)不需要预先声明,运行时(动态添加)
需要moc (Q_OBJECT)不需要(直接调用)
通过getter/setter访问通过property()/setProperty()访问
支持 NOTIFY 信号不支持信号通知
性能更快(编译优化)性能稍慢(运行时查找)
编译时检查编译时不进行类型检查,运行时检查(QVariant)

总结
Q_PROPERTY 声明的是静态属性,需要编译时定义,但更高效、功能更完整(支持信号、QML 绑定等)。
动态属性 (setProperty) 是运行时的,灵活但功能有限(无信号、类型不安全)。动态属性查找比静态属性慢,适合少量、不频繁访问的属性

优先用 Q_PROPERTY(性能、类型安全、信号支持)。
仅在需要运行时扩展时用动态属性(如临时存储、QSS 条件样式)。

参考引用:
Qt 中的属性系统(Property System)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值