QT特性:元对象系统

79 阅读2分钟

1:QT基础

1.1 QT核心特点

元对象提供了对象之间通信的信号和槽机制,动态属性系统,运行时类型。

1.1.1 信号和槽机制

信号和槽是一种回调机制,提供对象和对象之间的通信方式,增强代码的易维护性和可读性,这种机制意味着代码无需要紧密耦合。qt信号槽主要依赖于事件循环和元对象系统。

  • 基本用例
Button *button = new Button();
Display *display = new Display(); 
QObject::connect(button, &Button::clicked, display, &Display::showMessage);

此代码创建一个button和一个display实例,将button的clicked信号和Display的showMessage槽连接起来。

  • 信号和槽的高级用法

单个信号可以对应多个槽,多个信号也可以对应单个槽。connect的第五个参数可以是以下几种

  • 直接连接(DirectConnection):信号发射时,槽函数立即在同一个线程中执行。

  • 队列连接(QueuedConnection):信号发射时,槽函数被调入队列事件,在接收事件循环中执行,信号和槽在不同的线程。

  • 自动连接(AutoConnection)(默认参数):QT自动选择直接连接和队列连接,取决于信号发射者和接收者是否在用同一个线程中。

  • 使用sender()获得信号发射者 使用QOBject:sender()可以获得信号发射者的指针,从而对发射者进行从操作

    QPushButton* _btn = qobject_cast<QPushButton*>(sender());
    

1.1.2 动态属性系统

  • QObject是所有元对象系统类的基类。
  • 在一个类的private区域声明Q_OBJECT宏,使得类可以使用元对象系统的特性,如动态属性,信号和槽。
  • 元对象系统提供以下的一些功能:
  1. 返回类的名称字符串

    QObject* _obj = new QPushButton;
    qDebug() << _obj->metaObject()->className();
    

    上述会打印出:QPushButton

  2. 判断当前类是否是某个类的子类

    QObject* _obj = new QPushButton; 
    qDebug() << _obj->inherits("QTimer");
    qDebug() << _obj->inherits("QPushButton");
    qDebug() << _obj->inherits("QObject");
    

    打印出:false true true

  3. 投射出当前属于什么类型

    QObject* _obj = new QPushButton;
    QPushButton* _btn = qobject_cast<QPushButton*>(_obj);
    qDebug() << _btn->metaObject()->className();
    

    上述打印出:QPushButton

    使用动态投射,使得程序只可以在运行时对不同属性的对象做不同的处理。

1.1.3 属性系统

  1. Qt提供一个Q_PROPERTY()宏可以定义属性,也是基于元对象系统实现,在QObject的子类中,使用Q_PROPERTY()定义属性,格式如下:

    格式:

    Q_OBJECT
    Q_PROPERTY(type name READ getFunction WRITE setFunction NOTIFY notifySignal)
    

    实例:

     Q_OBJECT
     Q_PROPERTY(QString _name READ getName WRITE setName NOTIFY nameChange)
    
    • type name: 代表返回类型为type,名称为name的属性。
    • READ:设置一个读取属性的函数。
    • WRITE:设置一个设置属性值的函数。
    • NOTIFY:当属性值发生变化时发射此信号。

    无论是否设置上述属性,我们只要知悉属性名称都可以通过QObject:property()读取属性值,通过QObject:setProperty()设置属性值。