QProperty 理解与示例

QProperty 理解与示例

        该宏用来类中声明属性,跟踪类的数据变化。这些属性的行为类似于类中成员变量,但它们具有可通过元对象系统访问的附加功能。 可以使用通用函数 QObject::property() 和 QObject::setProperty() 来读取和写入属性,除了属性的名称之外,不需要知道有关所属类的任何信息。

        使用QProperty宏和使用信号-槽函数一样,类中必须包含Q_OBJECT宏类,它继承自 QObject,并在其私有部分中使用 Q_OBJECT 宏。在类的私有部分使用 Q_PROPERTY() 宏声明属性。注意声明语句结尾没有分号 

QObject Class | Qt Core 5.15.10

官网示例:The Property System | Qt Core 5.15.10 

#pragma once

#include <QObject>

class QPerson : public QObject
{
    Q_OBJECT
    Q_CLASSINFO("author", "Yan")
    Q_CLASSINFO("company", "GuangDong")
    Q_CLASSINFO("Version", "1.0")

    Q_PROPERTY(unsigned age READ getAge WRITE setAge NOTIFY ageChanged) 
    Q_PROPERTY(QString name MEMBER m_name) // 绑定成员变量
    Q_PROPERTY(int score MEMBER m_score)

private:
    unsigned m_age = 10;
    QString m_name;
    int m_score = 80;

public:
    explicit QPerson(QString name, QObject *parent = nullptr);
    inline unsigned getAge()
    {
        return m_age;
    };
    void setAge(unsigned value);
    void incAge();

signals:
    void ageChanged(unsigned value);
};

两种方式设置属性值:

1. 通过子类实例对象的 setProperty() 函数

boy = new QPerson("xiao ming");
boy->setProperty("age", 12);
boy->setProperty("sex", "Boy");  // 动态属性

2. 通过父类QObject的setProperty()函数
QObject *object = boy;// 子类QPerson到父类QObject的转换
object->setProperty("score", 80);

ui->SpinBoy->setProperty("isBoy", true);  // UI控件添加动态属性
ui->SpinGirl->setProperty("isBoy", false);

connect(boy, &QPerson::ageChanged, this, &Widget::on_ageChanged);  // Sender is Qperson
connect(girl, &QPerson::ageChanged, this, &Widget::on_ageChanged);

// 正常两个spinbox值变化,写两个connect链接不同槽函数(利用property做区分可以链接同一个)
connect(ui->SpinBoy, SIGNAL(valueChanged(int)), this, SLOT(spinBox_valueChanged(int)));   // sender is Spinbox
connect(ui->SpinGirl, SIGNAL(valueChanged(int)), this, SLOT(spinBox_valueChanged(int)));  

void Widget::on_ageChanged(unsigned value)
{
    QPerson *person = qobject_cast<QPerson *>(sender());// 槽函数中获取发送者

    QString name = person->property("name").toString();
    unsigned age = person->getAge();
    //    unsigned age = person->property("age").toInt();
    QString sex = person->property("sex").toString();

//    ui->txtEdit->appendPlainText(name + ", " + sex + ", " + QString::asprintf("age=%d", age)); 

    ui->txtEdit->appendPlainText(name + ", " + sex + ", " + QString("age= %1").arg(age));

    if (sex == "Boy")
    {
        ui->SpinBoy->setValue(age);
    } else
    {
        ui->SpinGirl->setValue(age);
    }
}

元对象信息的遍历

The Property System | Qt Core 5.15.10

void Widget::on_btnClassInfo_clicked()
{
    const QMetaObject *meta = boy->metaObject();

    ui->txtEdit->clear();

    ui->txtEdit->appendPlainText("===Meta object info===\n");
    ui->txtEdit->appendPlainText(QString("Class name:%1").arg(meta->className()));
    ui->txtEdit->appendPlainText(QString("Property"));

    for (int i = meta->propertyOffset(); i < meta->propertyCount(); i++)
    {
        const char *propName = meta->property(i).name();
        ui->txtEdit->appendPlainText(QString("Name=%1, Value=%2").arg(propName).arg(boy->property(propName).toString()));
    }

    ui->txtEdit->appendPlainText("");
    const QMetaObject *metaGirl = girl->metaObject();
    for (int i = metaGirl->propertyOffset(); i < metaGirl->propertyCount(); i++)
    {
        const char *propName = metaGirl->property(i).name();
        ui->txtEdit->appendPlainText(QString("Name=%1, Value=%2").arg(propName).arg(girl->property(propName).toString()));
    }

    ui->txtEdit->appendPlainText("");
    ui->txtEdit->appendPlainText("classInfo");
    for (int i = meta->classInfoOffset(); i < meta->classInfoCount(); ++i)
    {
        const QMetaClassInfo classInfo = meta->classInfo(i);
        ui->txtEdit->appendPlainText(QString("Name=%1; Value=%2").arg(classInfo.name()).arg(classInfo.value()));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yaked19

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值