【QT学习笔记】元对象系统

目录

元对象概念

运行时获取类的名称

通过名字动态设置和获取对象属性

Q_PROPERTY

属性的定义

属性的使用

Q_CLASSINFO

类信息的定义

类信息的使用


元对象概念

QT的元对象系统基于以下三个组件:

  • 类:QObject,所有需要使用元对象系统的基类
  • 宏:Q_OBJECT,在类的private部分声明
  • 编译器:元对象编译器(moc),为每个QObject子对象自动生成必要的代码来实现元对象特性

在程序编译的时候,会先使用元对象编译器读入C++的源文件,如果它发现了类里有Q_OBJECT声明,它就会创建一个C++源文件,为该类生成包含元对象实现的代码。

基于这样的一个元对象系统,QT实现了

  • 对象间的通信机制信号和槽
  • 属性系统
  • 类信息系统
  • ...

运行时获取类的名称

const QMetaObject *meta_obj = boy_->metaObject();
QString(meta_obj->className());

通过名字动态设置和获取对象属性

    ui->spinBox_boy->setProperty("is_boy", true);
    ui->spinBox_girl->setProperty("is_boy", false);

    QSpinBox *spinBox = qobject_cast<QSpinBox*>(sender());
    if(spinBox->property("is_boy").toBool())
        boy_->set_age(spinBox->value());
    else
        girl_->set_age(spinBox->value());

Q_PROPERTY

属性的定义

用宏 Q_PROPERTY() 定义属性,其使用格式如下:

Q_PROPERTY(type name (READ getFunction [WRITE setFunction] | MEMBER meznberName [(READ getFunction | WRITE setFunction)])
    [RESET resetFunction]
    [NOTIFY notifySignal]
    [REVISION int]
    [DESIGNABLE bool]
    [SCRIPTABLE bool]
    [STORED bool]
    [USER bool]
    [CONSTANT]
    [FINAL])

Q_PROPERTY 宏定义一个返回值类型为 type,名称为 name 的属性,用 READ、WRITE 关键字定义属性的读取、写入函数,还有其他的一些关键字定义属性的一些操作特性。属性的类型可以是 QVariant 支持的任何类型,也可以用户自定义类型。

Q_PROPERTY 宏定义属性的一些主要关键字的意义如下:

  • READ 指定一个读取属性值的函数,没有 MEMBER 关键字时必须设置 READ。
  • WRITE 指定一个设定属性值的函数,只读属性没有 WRITE 设置。
  • MEMBER 指定一个成员变量与属性关联,成为可读可写的属性,无需再设置 READ 和 WRITE。
  • RESET 是可选的,用于指定一个设置属性缺省值的函数。
  • NOTIFY 是可选的,用于设置一个信号,当属性值变化时发射此信号。
  • DESIGNABLE 表示属性是否在 Qt Designer 里可见,缺省为 true。
  • CONSTANT 表示属性值是一个常数,对于一个对象实例,READ 指定的函数返回值是常数,但是每个实例的返回值可以不一样。具有 CONSTANT 关键字的属性不能有 WRITE 和 NOTIFY 关键字。
  • FINAL 表示所定义的属性不能被子类重载。

属性的使用

只要知道属性名称,就可以通过 QObject::property() 读取属性值,并通过 QObject::setProperty() 设置属性值。例如:

Q_PROPERTY(unsigned age READ age WRITE set_age NOTIFY age_changed) 
Q_PROPERTY(QString name MEMBER name_)

//写
boy_->setProperty("score", 95);
boy_->setProperty("age", 10);

//读
const QMetaObject *meta_obj = boy_->metaObject();
QMetaProperty prop = meta_obj->property(i);
const char *prop_name = prop.name();
QString propValue = boy_->property(prop_name).toString();

QObject::setProperty() 函数可以在运行时为类定义一个新的属性,称之为动态属性。动态属性是针对类的实例定义的。

Q_CLASSINFO

使用宏Q_CLASSINFO可以为类的元对象定义“名称-值”信息

其实这个就相当于在类内定义了一些“名称-值”的结构体数据,这些数据在程序中可以通过一些接口读取到。

类信息的定义

class QMyClass:public QObject {
    Q_OBJECT
    Q_CLASSINFO("author", "xiaowang")
    Q_CLASSINFO("version ", "1.0.0")
  public:
    ...
};

类信息的使用

QMyClass myclass;
const QMetaObject *meta_obj = myclass.metaObject();
    
for(int i = 0; i < meta_obj->classInfoCount(); i++)
{
   QMetaClassInfo meta_class_info = meta_obj->classInfo(i);
        
   qDebug() << meta_class_info.name();
   qDebug() << meta_class_info.value();
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值