当前位置:   article > 正文

Qt属性系统及其用法

qt属性

前言

用过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进行修改和取值,还可以使用下面的方式进行操作

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

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

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

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

  1. QPushButton *button = new QPushButton;
  2. QObject *object = button;
  3. button->setDown(true);
  4. object->setProperty("down", true);

动态属性

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

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

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

QML中使用

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

  1. #include <QObject>
  2. #include <QColor>
  3. #include <qqml.h>
  4. class TestClass : public QObject
  5. {
  6. Q_OBJECT
  7. Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
  8. QML_ELEMENT
  9. public:
  10. explicit TestClass(QObject *parent = nullptr);
  11. const QColor &color() const;
  12. void setColor(const QColor &newColor);
  13. signals:
  14. void colorChanged();
  15. private:
  16. QColor m_color;
  17. };
  1. import QtQuick 2.15
  2. import QtQuick.Window 2.15
  3. import com.mycompany.qmlcomponents 1.0
  4. Window {
  5. width: 640
  6. height: 480
  7. visible: true
  8. title: qsTr("Hello World")
  9. TestClass {
  10. id: testClass
  11. color: Qt.red
  12. }
  13. Rectangle {
  14. width: 100
  15. height: 100
  16. color: testClass.color
  17. }
  18. }

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

  1. class TestClass : public QObject
  2. {
  3. Q_OBJECT
  4. Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)
  5. QML_ELEMENT
  6. public:
  7. explicit TestClass(QObject *parent = nullptr);
  8. signals:
  9. void colorChanged();
  10. private:
  11. QColor m_color;
  12. };

结语

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/445934
推荐阅读
相关标签
  

闽ICP备14008679号