Qt 元对象系统

1、QObject是所以使用元对象系统的类的基类,必须在类的开头使用Q_OBJECT宏才能使用元对象系统的特性。

2、元对象编译器MOC是一个预处理器。

3、元对象是对类的描述,包含类信息、方法、属性等元数据。

 

QObject类:

1、元对象(meta object):

每个QObject子类的实例都是一个元对象(静态变量staticMetaObject),函数metaObject()可以返回它的指针。

2、类型信息:QObject的inherits()函数可以判断继承关系。

3、动态翻译:函数tr()返回一个字符串的翻译版本。

4、对象树:表示对象间从属关系的树状结构。QObject提供了parent()、children()、findChildren()等函数。对象树中的某个对象被删除时,它的子对象也将被删除。

5、信号与槽:对象间的通信机制。

6、属性系统:可以使用宏Q_PROPERTY定义属性,QObject的setProperty()会设置属性的值或定义动态属性;property()函数会返回属性的值。

 

QMetaObejct类:

    QObject* object = new QPushButton;
    
    //QObject::metaObject()返回类关联的元对象。
    qDebug() << object->metaObject()->className();   //返回"QPushButton"
    
    QPushButton* pushbtn = qobject_cast<QPushButton*>(object);
    qDebug() << pushbtn->metaObject()->className();   //返回"QPushButton"
    
    //inherits()函数返回继承关系
    qDebug() << pushbtn->inherits("QObject");   //返回 true。pushbtn是继承自QObject
    qDebug() << pushbtn->inherits("QTimer");   //返回 false
    
    //superClass()函数返回父类的元对象
    qDebug() << object->metaObject()->superClass()->className();   //返回"QAbstractButton"

    object->setProperty("name", "tingtaishou");
    QString name = object->property("name").toString();

    const QMetaObject* meta = object->metaObject();
    int index = meta->indexOfProperty("name");
    QMetaProperty prop = meta->property(index);
    bool res = prop.isWritable();
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

    Q_CLASSINFO("author","tingtaishou")
    Q_CLASSINFO("version","1.0.0")

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QMetaProperty>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->metaObject()->classInfo(0).name();
    this->metaObject()->classInfo(0).value();
    this->metaObject()->classInfo(1).name();
    this->metaObject()->classInfo(1).value();
}

Widget::~Widget()
{
    delete ui;
}

 

信号与槽:

 

 

 

 

对象树:

 

 

 

 

元对象应用场景:

1、当一个窗口中有很多同类型的对象时,我们不需要将每个对象都写一个信号与槽,只需将所有对象都连接到同一个槽函数中,并在改槽函数中获取发送信号的对象(sender()函数),进而获取每个对象在创建时设置的不同的属性(ui->label_boy->setProperty("sex","boy"))从而区分不同的对象

 

posted @ 2023-07-16 15:22  远方是什么样子  阅读(74)  评论(0编辑  收藏  举报