Qt动态属性系统

1、创建动态属性

在标准C++中,为了保证封装性,我们经常声明一个私有变量,然后声明两个公有函数,即set函数和get函数。在Qt中我们可以使用宏Q_PROPERTY()宏来实现这些。一个属性可以使用常规函数QObject::property()和QObject::setProperty()进行读写,不用知道属性所在类的任何细节,除了属性的名字。

Q_PROPERTY()原型:

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

 
// 中括号中的内容为可选项 
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]             //不能被重写      
)

2、Q_PROPERTY宏参数类型

1. type name

属性类型可以是QVariant支持的任何类型,也可以是用户定义的类型;

2. READ 和 MEMBER

如果没有MEMBER,则必须要有READ。

READ 后面定义获取属性值的函数,该函数是const;

WRITE 设置属性值,是可选的;

MEMBER 如果一个属性不需要 READ ,但又想使用属性系统,可以使用MEMBER来注册,MEMBER后面是成员变量的名字;

3. RESET

可选,将属性设置为默认值,该RESET函数必须返回void并且不带参数。

4. NOTIFY

可选,NOTIFY 后面跟该类中已经定义的一个信号函数,只要该属性的值发生更改,就会发出该信号。这个信号函数必须采用零个或一个参数,该参数必须与属性的类型相同。

5. REVISION int

可选,版本信息(通常用于QML)。

6. DESIGNABLE bool

可选,表示属性是否能在GUI设计工具的属性编辑器中可见(例如,Qt Designer)。大多数属性是DESIGNABLE(默认为true)。

7. SCRIPTABLE bool

可选,SCRIPTABLE属性表示脚本引擎是否应该可以访问此属性(默认为true)

8. STORED bool

可选,该属性是单独存在还是从其他值中获取的。大部分是true,一个反例是QWidget::minimumWidth()的值从QWidget::minimumSize()中获取,因此它的STORED为false。

9. USER bool

可选,表示是否可以被用户所编辑。

10. CONSTANT

可选,CONSTANT表明属性值是常量,不可更改,因此不能有WRITE方法或NOTIFY信号。对于给定的对象实例,常量属性的READ方法每次调用时都必须返回相同的值。对于对象的不同实例,该常数值可以是不同的。

11. FINAL

可选,FINAL表示属性不会被派生类覆盖,在某些情况下,这可用于性能优化。

3、演示

示例:

1.新建桌面应用程序Widget,新建一个C++类MyPropertyClass,并声明Q_PROPERTY宏

#include <QObject>
 
class MyPropertyClass : public QObject
{
    Q_OBJECT
    //声明1_PROPERTY宏
    Q_PROPERTY(QString mask READ mask WRITE setMask NOTIFY maskChanged)
public:
    explicit MyPropertyClass(QObject *parent = nullptr);
    //只读
    QString mask() const;
    //只写
    void setMask(QString strMaskNum);
signals:
    void maskChanged(QString strMaskNum);
 
private:
    //用来保存mask的值
    QString m_mask;
};

读写函数的实现:

QString MyPropertyClass::mask() const
{
    return m_mask;
}
 
void MyPropertyClass::setMask(QString strMaskNum)
{
    m_mask=strMaskNum;
    emit maskChanged(strMaskNum);
}

4.在widget.h中声明一个槽方法

public slots:
    void maskChanged(QString str);  //槽方法与信号保持一致

槽方法实现

void Widget::maskChanged(QString str){    qDebug()<<"新的值为:"<<str;}

在Widget.cpp文件中,在构造函数里将槽方法与MyPropertyClass类的动态属性的信号连接,并动态属性赋值

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
MyPropertyClass *myPc=new MyPropertyClass;
connect(myPc,SIGNAL(maskChanged(QString)),this,SLOT(maskChanged(QString)));
myPc->setMask("1000个");
}

执行结果:

 

4、通过基类读写动态属性

1.读属性

调用动态属性写函数将属性赋值为“1000个”,属性值被更改就会发送了maskChanged信号,我们又在Widget程序中将一个槽方法与该信号连接,在槽方法中输出修改的属性值。

也可以使用父类的property和setproperty方法获取修改属性值

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    MyPropertyClass* mypC=new MyPropertyClass;
    mypC->setMask("10000个口罩");//调用写方法
    
    //通过基类查看动态属性值
    QObject*obj=mypC;
    qDebug()<<"QObject读取的属性值"<<obj->property("mask").toString()
}

执行结果

 

2.改属性

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    MyPropertyClass *myPc=new MyPropertyClass;
    connect(myPc,SIGNAL(maskChanged(QString)),this,SLOT(maskChanged(QString)));
    myPc->setMask("1000个");
    QObject *obj=myPc;
    //父类调用property读属性
    qDebug()<<"obj读属性:"<<obj->property("mask").toString();
    //父类调用setProperty修改属性
    obj->setProperty("mask","2000个");
    qDebug()<<"obj读取修改后属性:"<<obj->property("mask").toString();
}

执行结果:

 

动态属性系统优点在于其继承自QObject,我们只需要一个QObject和子类的类名,便可以操作不同类的动态属性

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值