Qt之自定义属性Q_PROPERTY专题(1)充分理解其概念以及用途

简介: Qt之自定义属性Q_PROPERTY专题(1)充分理解其概念以及用途

1、先看基本概念


发现Qt类定义中有许多Q_PROPERTY的东西,比如最常用的QWidget的类定义:


class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice

{

   Q_OBJECT

   Q_DECLARE_PRIVATE(QWidget)

   Q_PROPERTY(bool modal READ isModal)

   Q_PROPERTY(Qt::WindowModality windowModality READ windowModality WRITE setWindowModality)

   Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)

   Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry)

   Q_PROPERTY(QRect frameGeometry READ frameGeometry)

   Q_PROPERTY(QRect normalGeometry READ normalGeometry)

   Q_PROPERTY(int x READ x)

   Q_PROPERTY(int y READ y)

   Q_PROPERTY(QPoint pos READ pos WRITE move DESIGNABLE false STORED false)

   Q_PROPERTY(QSize frameSize READ frameSize)

   Q_PROPERTY(QSize size READ size WRITE resize DESIGNABLE false STORED false)

   Q_PROPERTY(int width READ width)

   Q_PROPERTY(int height READ height)

   Q_PROPERTY(QRect rect READ rect)

   Q_PROPERTY(QRect childrenRect READ childrenRect)

   Q_PROPERTY(QRegion childrenRegion READ childrenRegion)

   Q_PROPERTY(QSizePolicy sizePolicy READ sizePolicy WRITE setSizePolicy)

   Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize)

   Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize)

......

Qt提供了一个绝妙的属性系统。跟那些由编译器提供的属性差不多。然而,作为一个独立于编译器和平台的库,Qt不依赖于非标准的编译特性,比如__property 或[property]。Qt可以在任何平台上的标准编译器下编译。Qt属性系统基于元数据对象系统--就是那个提供了对象内置信号和槽通讯机制的家伙。


   Q_PROPERTY()是一个宏,用来在一个类中声明一个属性property,由于该宏是qt特有的,需要用moc进行编译,故必须继承于QObject类。


Q_PROPERTY(type name

  READ getFunction

  [WRITE setFunction]

  [RESET resetFunction]

  [NOTIFY notifySignal]

  [DESIGNABLE bool]

  [SCRIPTABLE bool]

  [STORED bool]

  [USER bool]

  [CONSTANT]

  [FINAL])

下面是一些典型的声明属性的示例:


Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)

Q_PROPERTY(bool animation READ getAnimation WRITE setAnimation)

Q_PROPERTY(QColor barColor READ getBarColor WRITE setBarColor)

一个属性的行为就像类的数据成员,但是它还具有附加的特性,这些特性可以被元数据对象系统操作。这些特性是:

需要一个READ访问器函数。用于读属性的值。理想情况下,有一个不变的函数用于此目的,并且它必须返回属性的类型的值或指针或引用。例如,QWidget::focus是一个只读的属性,它对应一个读函数:QWidget::hasFocus()。

一个可选的WRITE访问器函数。它用于设置属性的值。它必须返回空并且至少具有一个参数,参数是属性类型的值或指针或引用。例如:QWidget::enabled具有WRITE函数QWidget::setEnable()。只读属性不需要写函数。例如,QWidget::focus没有对应的写函数。

一个可选的RESET函数。用于设置属性的值到它的默认值。例如:QWidget::cursor具有典型的READ和WRITE函数,QWidget::cursor()和QWidget::setCursor(),并且它也具有一个RESET函数,QWidget::unsetCursor()。RESET函数必须返回void并且不带有任何参数。

一个可选的NOTIFY信号。如果被定义了,信号将在属性的值改变时发出。信号必须带有一个参数,这个参数的类型必须与属性相同;参数保存的是属性的新值。

一个DESIGNABLE变量表明此属性是否在界面设计器的属性编辑器中出现。大多数属性是可见的,除了为这个变量传入true或false,你还可以指定一个bool型的成员函数。

SCRIPTABLE变量表明这个属性是否可以被一个脚本引擎操作(默认是true)。你也可以赋予它true或false或bool型函数。

STORED变量表明了属性是否被认为是独立存在还是依赖于其它的值而存在。它也表明是否在保存对象状态时保存此属性的值。大多数属性都是需要保存的,但是,如QWidget::minimumWidth()就是不被保存的,因为它的值是从另一个属性QWidget::minimumSize()得来的。

USER变量表明属性是否被设计为面向用户的或用户可修改的类属性。通常,每个类只有一个USER属性。例如,QAbstractButton::checked是按钮类的用户可修改属性。注意QItemDelegate获取和设置widget的USER属性。

CONSTANT的出现表明属性的值是不变的。对于一个object实例,常量属性的READ方法在每次被调用时必须返回相同的值。此常量值可能在不同的object实例中不相同。一个常量属性不能具有WRITE方法或NOYIFY信号。

FINAL变量的出现表明属性不能被派生类所重写。有些情况下,这可以用于效率优化,但不是被moc强制的。程序员必须永远注意不能重写一个FINAL属性。

READ,WRITE和RESET函数都可以被继承。它们也可以是虚函数。当它们在被多重继承中被继承时,它们必须出现在第一个被继承的类中。属性的类型可以是被QVariant支持的所有类型,也可以是用户定义的类型。在下面的例子中,类QDate被当作用户自定义类型。


Q_PROPERTY(QDate data READ getDate WRITE setDate)

因为QDate是用户定义的,你必须包含<QDate>头文件。


   对于QMap,QList和QValueList属性,属性的值是一个QVariant,它包含整个list或map。注意Q_PROPERTY字符串不能包含逗号,因为逗号会划分宏的参数。因此,你必须使用QMap作为属性的类型而不是QMap<QString,QVariant>。为了保持一致性,也需要用QList和QValueList而不是QList<QVariant>和QValueList<QVariant>。


2、Q_PROPERTY代码的写法:


class Test : public QObject {  

 

Q_OBJECT  

 

Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)  

 

public:  

 

Test(QObject *parent = 0) : QObject(parent) {}  

 

virtual ~Test(){}  

 

void setEnabled(bool e) { enabled = e; }  

 

bool isEnabled() const { return enabled; }  

 

private:  

 

bool enabled;  

 

};  

然后在主函数中添加:


Test *test = new Test;  

 

test->setProperty("enabled", true);  

 

//test->setEnabled(true);        //ok also work  

 

if(test->property("enabled").toBool()) .....


3、提升为自定义QWidget的例子:


(1)头文件中定义了一个minValue 的属性,如下:


class BarRuler : public QWidget
{
    Q_OBJECT    
    Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)
public:
    explicit BarRuler(QWidget *parent = 0);
    ~BarRuler();
private:    
    double minValue;
public:    
    double getMinValue()            const;
public slots:
    void setRange(double minValue, double maxValue);
};

(2)cpp文件实现如下:


#include "barruler.h"
BarRuler::BarRuler(QWidget *parent) : QWidget(parent)
{    
    minValue = 0;
}
BarRuler::~BarRuler()
{
}
double BarRuler::getMinValue() const
{
    return this->minValue;
}
void BarRuler::setMinValue(double minValue)
{
    this->minValue = minValue;
    update();
}

(3)打开Qt设计师界面工具,然后


(3.1)先拖入一个widget控件


(3.2)在其上右键选择“提升为”BarRuler,即提升为自定义部件


(3.3)点击属性栏的加号,选择其它类型,如图


image.png


(3.4)类型和名称都要和头文件里定义的相同,如图


image.png


(3.5)在属性栏就会出现对应的动态属性,如图


image.png


(3.6)修改数值,就会改变相对应定义的属性了



4、QSS的使用案例


参见我的另一篇博文 https://libaineu2004.blog.csdn.net/article/details/88106845



5、QML的使用案例


参见我的另一篇博文 https://libaineu2004.blog.csdn.net/article/details/88310218



x、参考文献


https://blog.csdn.net/wzs250969969/article/details/78418124


https://www.cnblogs.com/MakeView660/p/10813829.html


相关文章
|
6月前
|
程序员 数据安全/隐私保护 C++
【qt】动态属性
【qt】动态属性
76 1
|
1月前
(8)Qt中的自定义信号
本文介绍了如何在Qt框架中创建和使用自定义信号,并通过一个父子窗口切换的示例来展示自定义信号的实现和应用。
65 3
(8)Qt中的自定义信号
|
1月前
(7)Qt中的自定义槽(函数)
这篇文章介绍了在Qt中如何定义和使用自定义槽函数,包括类成员函数、静态类成员函数、全局函数和lambda表达式作为槽函数的示例,以及使用lambda表达式时的注意事项。
33 2
(7)Qt中的自定义槽(函数)
|
3月前
|
搜索推荐 C++
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
70 4
|
3月前
|
前端开发 搜索推荐 API
【Qt 学习笔记】QWidget的styleSheet属性 | RGB | 在线调色板
【Qt 学习笔记】QWidget的styleSheet属性 | RGB | 在线调色板
202 5
|
3月前
【qt】自定义对话框(2)
【qt】自定义对话框(2)
23 0
|
3月前
【qt】自定义对话框(1)
【qt】自定义对话框(1)
30 0
|
4月前
|
C++
Qt中的信号与槽如何学习?(包括自定义信号)这篇文章告诉你
以现实中的事件来举例的话,例如有两把不同颜色的信号枪,分别是红色,绿色,打响不通颜色的信号枪会触发不同的槽发生,比如说打响红色这个人就跑步,绿色就走步,但是还有一个很重要的机制,那就是连接,我们需要把信号枪去跟这个人的动作连接起来。 如果上面理解没问题的话我们可以把信号和槽看成两个工具,我们最重要的是如何去把这两个工具连接起来。 它的作用可以让我们更加灵活的去使用不同窗口间的切换以及某些事件的连接。
|
6月前
|
C语言 容器
【qt】动态属性(下)
【qt】动态属性(下)
67 1
|
6月前
|
Windows
Qt 目录操作(QDir 类)及展示系统文件实战 & QFilelnfo 类介绍和获取文件属性项目实战
Qt 目录操作(QDir 类)及展示系统文件实战 & QFilelnfo 类介绍和获取文件属性项目实战
Qt 目录操作(QDir 类)及展示系统文件实战 & QFilelnfo 类介绍和获取文件属性项目实战