Qt属性系统及其用法

7 篇文章 6 订阅

前言

用过Qt的都知道Qt的元对象系统,Qt的元对象系统为对象间通信、运行时类型信息和动态属性系统提供了信号和插槽机制。今天我们就来认识下Qt的动态属性系统。

初识Qt属性系统

引入官方文档的介绍:

Qt提供了一个复杂的属性系统,类似于一些编译器供应商提供的系统。然而,作为一个独立于编译器和平台的库,Qt不依赖于像__property或[property]这样的非标准编译器特性。Qt解决方案可以在Qt支持的每个平台上与任何标准C++编译器一起工作。它基于元对象系统,该系统也通过信号和插槽提供对象间的通信。

使用Qt动态属性,需要继承自QObject类,并使用宏 Q_PROPERTY() 

我们熟知的QWidget就定义了很多的属性

具体结构为:

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]
           [REQUIRED])

可以看到字段很多,具体可自行查看官方文档。下面介绍Q_PROPERTY的常见用法。

用法

项目开发中,如果使用的是Qt Creator,输入Q_PROPERTY时,自动补全功能就会联想出一些可选项,选择附带有type、READ、WRITE、NOTIFY字段的选项,这是一个最常规的用法,提供类型、读写和信号,能够满足大部分需求了。

定义

 输入完成后,使用快捷键Alt+回车,就会提示生成对应的变量和函数,确认后就会自动补全

 还可以鼠标光标放在Q_PROPERTY,然后右键→Refactor也是一样的效果

 运用

按照上面的定义方式可以使用定义的接口setName和name进行修改和取值,还可以使用下面的方式进行操作

bool setProperty(const char *name, const QVariant &value);
QVariant property(const char *name) const;

name就是type对应的属性名称,使用setProperty的方式的一个好处就是只需要知道属性名称和类型,另外使用setName的方式速度会更快,两种方式各有利弊吧

setProperty("name", "1111");
qDebug() << __FUNCTION__ << "song" << "name:" << m_name << property("name").toString();

在父类中定义的属性,子类也是可以使用的

QPushButton *button = new QPushButton;
QObject *object = button;

button->setDown(true);
object->setProperty("down", true);

动态属性

动态属性就是没有手动添加Q_PROPERTY,直接调用setProperty,如果该属性没有,则会自动添加,提供一个invalid的QVariant就可以移除

setProperty("name22", "1111");
qDebug() << __FUNCTION__ << "song" << "name22:" << property("name22").toString();
setProperty("name22", QVariant());
qDebug() << __FUNCTION__ << "song" << "name22:" << property("name22");

需要注意的是动态属性并不会添加到元对象系统中,所以元对象相关的功能就用不了,如无法在QML中使用属性

QML中使用

直接看代码就好了, 这也是C++与QML交互运用

#include <QObject>
#include <QColor>
#include <qqml.h>

class TestClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
    QML_ELEMENT
public:
    explicit TestClass(QObject *parent = nullptr);

    const QColor &color() const;
    void setColor(const QColor &newColor);

signals:
    void colorChanged();

private:
    QColor m_color;

};
import QtQuick 2.15
import QtQuick.Window 2.15
import com.mycompany.qmlcomponents 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    TestClass {
        id: testClass
        color: Qt.red
    }

    Rectangle {
        width: 100
        height: 100
        color: testClass.color
    }
}

还有更简单的定义方式,把READ和WRITE去掉,只保留NOTIFY,这样就可以把setter和getter的接口去掉,这样也是可以的,代码量更少,QML中使用NOTIFY是必须的,在C++中对属性进行操作则可以使用前面介绍的setProperty

class TestClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)
    QML_ELEMENT
public:
    explicit TestClass(QObject *parent = nullptr);

signals:
    void colorChanged();

private:
    QColor m_color;

};

结语

Qt属性系统贯穿整个Qt框架,作为Qt框架的使用者必须要有所了解,并且会基本的运用,本篇文章就介绍一些常见的点。

最后的QML的完整demo地址:GitHub

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值