ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

简要源码分析Q_PROPERTY

2022-09-08 08:31:04  阅读:255  来源: 互联网

标签:Priority 简要 QObject priority 源码 MyClass PROPERTY public


本文不打算像文档一样翻译Q_PROPERTY,而是从源码的角度来看看怎么使用Q_PROPERTY

QT的PROPERTY官方的定义,为了保持格式,我特地截屏,如下

毫无疑问, QT的moc系统对Q_PROPERTY有特别的处理,我们现在看看他处理了什么.
首先,定义一个类Test,代码如下:

class Test : public QObject
{
    Q_OBJECT
public:
    explicit Test(QObject *parent = 0);
    ~Test();
};

QT的moc会自动生成moc_test.cpp,备份一下这个文件
然后,加上一个属性描述:Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
对比官方的定义,我标识一下,看得更清楚

增加Q_PROPERTY后,的代码如下,只增加了一行代码:

class Test : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
public:
    explicit Test(QObject *parent = 0);
    ~Test();
};

重新编译,由于我们没有实现函数isEnabled和setEnabled,所以是编译不过的,出现如下错误信息:

但这说明moc已经工作了,并且生成了额外的代码,我们和刚刚没有加Q_PROPERTY的代码对比一下看看:

由上图可以看出,增加了一些properties的标识,增加了字符串"bool"和"enabled"
并且qt_metacall里增加了一些函数调用,如下图:

从图中我们可以看出,我们必须要自己实现函数isEnabled和setEnabled,否则别想编译过.
那好,增加这两个函数的实现代码

class Test : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
public:
    explicit Test(QObject *parent = 0);
    ~Test();

    void setEnabled(bool e) { m_bEnable = e; }
    bool isEnabled() const { return m_bEnable; }

private:
    bool m_bEnable;
};

我们实现了setEnabled和isEnabled,
然而,你可能会反问,这不就是个属性嘛,为了防止直接访问内部变量,我也经常写这样的代码啊.这样写的好处是保护成员变量不被意外修改.
然而,我想说的是,QT属性系统的精髓在于,可以用QObject的方法来访问继承类的属性.
还记得前面吗,增加了字符串"bool"和"enabled"
来,我们看看如何用基类来访问属性.

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    Test t;
    QObject *p = &t;

    qDebug() << t.isEnabled() << endl;
    qDebug() << p->property("enabled").toBool() << endl;

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

    qDebug() << t.isEnabled() << endl;
    qDebug() << p->property("enabled").toBool() << endl;


    return a.exec();
}

运行结果为:
false
false
true
true

这就充分说明了,如何使用QObject的设置和访问属性

=======================   另一个例子的分割线   ======================

接下来再看一个QT文档中的例子,分析手法和上面一样
首先,来个最简单的,类定义如下:

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = 0);
    ~MyClass();
};

备份自动生成的moc_myclass.cpp
增加一个enum,并指明是Q_ENUMS

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = 0);
    ~MyClass();

    enum Priority {High, Low, VeryHigh, VeryLow};
    Q_ENUMS(Priority)
};

看下对比,enum增加了哪些东西

可以看出,增加了enum的一些东西,还增加了字符串"Priority", "High", "Low", "VeryHigh", "VeryLow"
接着,增加一行属性定义
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
为了方便查看,我还是标识出来

增加后代码如下(由于我们增加了NOTIFY,所以还要增加一个signal priorityChanged, 不然moc编译不过):

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
public:
    explicit MyClass(QObject *parent = 0);
    ~MyClass();

    enum Priority {High, Low, VeryHigh, VeryLow};
    Q_ENUMS(Priority)
signals:
    void priorityChanged(Priority);

};

对比一下:

增加了字符串"priorityChanged(Priority)"
注意,增加字符串"priority",这个字符串是用来描述属性priority Q_PROPERTY(Priority priority ...)
继续比较

和上面分析Test类一样,不同点在于现在这个类增加了一个signal

好了,我们把类实现完全,增加函数setPriority和priority

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
public:
    explicit MyClass(QObject *parent = 0);
    ~MyClass();

    enum Priority {High, Low, VeryHigh, VeryLow};
    Q_ENUMS(Priority)
signals:
    void priorityChanged(Priority);

public:
    void setPriority(Priority priority)
    {
        m_priority = priority;
        emit priorityChanged(priority);
    }
    Priority priority() const
    { return m_priority; }

private:
    Priority m_priority;
};

然后,我们用同样的手法,写一个调用测试

    MyClass *myinstance = new MyClass;
    QObject *object = myinstance;

    object->setProperty("priority", "VeryHigh");
    qDebug() << object->property("priority").toUInt() << endl;


    delete myinstance;

打印输出
2
2在enum Priority {High, Low, VeryHigh, VeryLow}中就表示VeryHigh

总结:
QT的属性系统为我们提供了在基类访问子类的属性的方法,非常NICE.

参考:
https://doc.qt.io/qt-5/properties.html
https://blog.csdn.net/wzs250969969/article/details/78418124

代码: http://q1024.com/files/qt_window-master.zip 000200目录

标签:Priority,简要,QObject,priority,源码,MyClass,PROPERTY,public
来源: https://www.cnblogs.com/xingzaicpp/p/16667976.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有