精华内容
下载资源
问答
  • Qt是一个用标准C++编写的跨平台开发类库,它对标准 C++ 进行了扩展,引入了元对象系统、信号与槽、属性等特性,使应用程序的开发变得更高效。 本节将介绍 Qt 的这些核心特点,对于理解和编写高效的 Qt C++ 程序是...

    Qt 是一个用标准 C++ 编写的跨平台开发类库,它对标准 C++ 进行了扩展,引入了元对象系统信号与槽属性等特性,使应用程序的开发变得更高效。

    本节将介绍 Qt 的这些核心特点,对于理解和编写高效的 Qt C++ 程序是大有帮助的。

     

    Qt 的元对象系统

    Qt 的元对象系统(Meta-Object System)提供了对象之间通信的信号与槽机制运行时类型信息动态属性系统

    声明为元对象类型:Q_DECLARE_METATYPE(Annotation*)

    class Annotation: public QObject {
    Q_OBJECT
    public:
    	Annotation(QObject* parent = 0);
    	virtual ~Annotation();
    
    private:
    	
    };
    
    Q_DECLARE_METATYPE(Annotation*)
    

    通常不需要声明为元对象类型,继承QObject 类,声明宏Q_OBJECT就可以了。

    元对象系统由以下三个基础组成:

    1. QObject 类是所有使用元对象系统的类的基类。
    2. 在一个类的 private 部分声明 Q_OBJECT宏,使得类可以使用元对象的特性,如动态属性、信号与槽。
    3. MOC(元对象编译器)为每个 QObject 的子类提供必要的代码来实现元对象系统的特性。

     构建项目时,MOC 工具读取 C++ 源文件,当它发现类的定义里有 Q_OBJECT 宏时,它就会为这个类生成另外一个包含有元对象支持代码的 C++ 源文件,这个生成的源文件连同类的实现文件一起被编译和连接。

    元对象提供的功能:

    (1)信号与槽;

    (2)除了信号与槽机制外,元对象还提供如下一些功能:

    • QObject::metaObject() 函数返回类关联的元对象,元对象类 QMetaObject 包含了访问元对象的一些接口函数,例如 QMetaObject::className() 函数可在运行时返回类的名称字符串。
      QObject *obj = new QPushButton;
      obj->metaObject()->className (); //返回"QPushButton"
    • QMetaObject::newInstance() 函数创建类的一个新的实例。
    • QObject::inherits(const char *className) 函数判断一个对象实例是否是名称为 className 的类或 QObject 的子类的实例。例如:
    QTimer *timer = new QTimer; // QTimer 是 QObject 的子类
    timer->inherits ("QTimer"); // 返回 true
    timer->inherits ("QObject");  // 返回 true
    timer->inherits ("QAbstractButton");//返回 false,不是 QAbstractButton 的子类
    • QObject::tr() 和 QObject::trUtf8() 函数可翻译字符串,用于多语言界面设计,后续章会专门介绍多语言界面设计。
    • QObject::setProperty() 和 QObject::property() 函数用于通过属性名称动态设置和获取属性值。

     对于 QObject 及其子类,还可以使用 qobject_cast() 函数进行动态投射(dynamic cast)。例如,假设 QMyWidget 是 QWidget 的子类并且在类定义中声明了 Q_OBJECT 宏。创建实例使用下面的语句:

    QObject *obj = new QMyWidget;

    变量 obj 定义为 QObject 指针,但它实际指向 QMyWidget 类,所以可以正确投射为 QWidget,即:

    QWidget *widget = qobject_cast<QWidget *>(obj);
    从 QObject 到 QWidget 的投射是成功的,因为 obj 实际是 QMyWidget 类,是 QWidget 的子类。也可以将其成功投射为 QMyWidget,即:
    QMyWidget *myWidget = qobject_cast<QMyWidget *>(obj);
    投射为 QMyWidget 是成功的,因为 qobject_cast() 并不区分 Qt 内建的类型和用户自定义类型。但是,若要将 obj 投射为 QLabel 则是失败的,即:
    QLabel * label = qobject_cast<QLabel *>(obj);

    这样投射是失败的,返回指针 label 为 NULL,因为 QMyWidget 不是 QLabel 的子类。

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

     

    属性系统

    属性定义

    Qt 提供一个 Q_PROPERTY() 宏可以定义属性,它也是基于元对象系统实现的。Qt 的属性系统与 C++ 编译器无关,可以用任何标准的 C++ 编译器编译定义了属性的 Qt C++ 程序。

    在 QObject 的子类中,用宏 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 表示所定义的属性不能被子类重载。

    QWidget 类定义属性的一些例子如下:

    Q_PROPERTY(bool focus READ hasFocus)
    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
    Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)

    属性的使用

    不管是否用 READ 和 WRITE 定义了接口函数,只要知道属性名称,就可以通过 QObject::property() 读取属性值,并通过 QObject::setProperty() 设置属性值。例如: 

    QPushButton *button = new QPushButton;
    QObject *object = button;
    object->setProperty("flat", true);
    bool isFlat= object->property ("flat");

    动态属性

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

    动态属性可以使用 QObject::property() 查询,就如在类定义里用 Q_PROPERTY 宏定义的属性一样。

    例如,在数据表编辑界面上,一些字段是必填字段,就可以在初始化界面时为这些字段的关联显示组件定义一个新的 required 属性,并设置值为“true”,如:

    editName->setProperty("required", "true");
    comboSex->setProperty("required", "true");
    checkAgree->setProperty("required", "true");
    

    然后,可以应用下面的样式定义将这种必填字段的背景颜色设置为亮绿色。

    *[required="true"]{background-color:lime}

     

    类的附加信息

    属性系统还有一个宏 Q_CLASSINFO(),可以为类的元对象定义“名称——值”信息,如:

    class QMyClass:public QObject {
        Q_OBJECT
        Q_CLASSINFO("author", "Wang")
        Q_CLASSINFO ("company", "UPC")
        Q_CLASSINFO("version ", "3.0.1")
      public:
        ...
    };

    用 Q_CLASSINFO() 宏定义附加类信息后,可以通过元对象的一些函数获取类的附加信息,如 classlnfo(int) 获取某个附加信息,函数原型定义如下:

    QMetaClassInfo QMetaObject::classInfo(int index) const

    返回值是 QMetaClassInfo 类型,有 name() 和 value() 两个函数,可获得类附加信息的名称和值。

    展开全文
  • Qt元对象系统解析(一)

    万次阅读 多人点赞 2016-05-06 15:43:17
    Qt信号与槽是一个很好机制,不如说Qt元对象系统很强大。这也是大家讲Qt就必须将信号与槽,讲信号与槽就要讲Qt元对象系统。当然初学者知道怎么用就OK啦,当然随着你写的代码越多,接触的平台越多的时候,你就会...

    说Qt信号与槽是一个很好机制,不如说Qt的元对象系统很强大。这也是大家讲Qt就必须将信号与槽,讲信号与槽就要讲Qt的元对象系统。当然初学者知道怎么用就OK啦,当然随着你写的代码越多,接触的平台越多的时候,你就会好奇Qt是如何把两个(多个)任意不相关(必须都继承与QObject)的对象联系在一起的。我们围绕一些问题来认识一下Qt元对象系统:

    • 什么是Qt元对象系统,它包含了哪些内容,它在我们的程序中做了什么?
    • moc工具是什么,Q_OBJECT宏是什么?
    • 元对象系统如何工作在Qml、C++、Javvascrip的混合编程的?
    • 信号与槽机制、Qt事件机制、MFC消息机制三者的区别是什么?
    • 信号与槽在单线程与多线程中是如何工作的?
    • 如何在信号与槽机制中,传递自定义类型参数?
      什么是Qt元对象系统
      元对象系统是一个基于标准C++的扩展,为Qt提供了1、信号与槽机制2、实时类型信息3、动态属性系统。
      这个元对象主要基于三个东西:

    • Object类。大家都知道QObject类是Qt的核心类,很多Qt类都是由它继承而来,那它具体到底是什么东西呢?我们一起去看下Object的Detail Description我们一起来趴一下它的主要特性:
      (1)它是对象模型的核心,信号与槽是基于对象模型的(两个对象的连接),而它是对象模型的核心。体现在我们常用的QObject::connect()函数上,我们后面会分析这个conncet()源码,趴一下它是怎么工作的。
      (2)对象的组织方式以树形结构的。这也就是Qt框架那章Core模块的一个特性“树形对象模型”。我们常用相关的函数体现在QObject::setParent()、QObject::findChild()、QObject::findChilren()这几个函数上。这种树形结构保持了众多对象之间的严密的父子、逻辑关系。
      (3)每一个对象都有一个独立的名字,并且可以查出该对象的继承关系。这些对象不同的名字是我们使用findChild()函数的关键,也是我们在Qml、C++混合编程时的关键。这里QObject有这个属性,并不是它自己实现的,是QMetaobject帮助实现的,QMetaObject是设置这些属性规则,并建立对象们之间的关系的关键。(每个人都有自己名字手机QQ,但是你们怎么相互联系呢,它就是帮助建立通讯录)
      (4)对象在销毁时会发出一个信号。这里没什么好多说的。
      (5)添加安装事件过滤器。让对象接受或者不接受某些事件以及事件的处理。我们常用到的有mouseEvent()、timeEvent(),在某些没有继承Object类中是不能使用这些函数的,如QGraphicsItem以及它派生出来的其他图元类。后面我们会讲事件与信号槽的区别。
      前面(1)(2)(3)是Object与元对象系统紧密联系的属性,其他属性大家可以去看看帮助文档扒一扒,小白英文太烂。到这里你只要明白为什么元对象非要和QObject相关就行啦。

    • Q_OBJECT。简单理解就是一些宏定义代码,就是你们自己定义的一些类、类的信号、槽函数、(Qml混合编程的属性、自己注册的Qt数据类型等)这么多属性,怎么保存到通讯录里面呢?就是通过这个宏定义的函数,帮助你们实现的,后面会结合moc文件讲解这个函数是做什么的。
    • moc(Meta-Object-Compiler)元对象编译器,从概念上和其他编译器一样来理解就好了。signals、slots关键字并不是标准C++里面的东西,代码最后要交给C++编译器,那么就需要把这部分转化成C++编译器认识的东西,这个工作就是moc来完成了。这里需要注意的是,moc过程是发生在预编译之前的,简单说就是moc之后每一个包含Q_OBJECT宏头文件,都会根据该头文件里面的signals、slots、Q_MENU l来生成以moc_XXXX(自定义类名)的.cpp文件,我们常用IDE的构建生成的.o文件,就是最终的目标文件(包含moc生成的cpp)。这个中间生成用qamke生成Makefile可以清楚的看到编译文件的连接情况。后面讲Qt工程的时候会讲解Makefile。这里大家想要理解moc更多的使用规则,帮助里面输入moc查看帮助文档,这里推荐也个中文翻译版(小白英语实在太烂)http://www.kuqin.com/qtdocument/moc.html
      其实大家都知道这三个基本原则,小白在这里也碰到一个疑问,在《零基础学Qt4编程》里面说moc在生成cpp文件的同时,也会生成头文件XXXX.moc.h格式,很显然小白是没有这个文件的,在帮助里看到的也是read a C++ source file。C++编译器在预编译处理过程中就是处理头文件,如果Qt没有转换头文件,C++编译器怎么认识signals、slots这样的关键字呢?在此不知道有没有熟悉编译原理里的大牛给小白普及一下。
      元对象系统除了提供信号与槽(communication between objects ,the main reason for introducing the system。主要特性)。我们常用的国际化QObject::tr()、qsTr()还有常用的QObject::setProperty()、QObject::property()。

      到这里我们大致的理解开始我们提出问题的前三个,每个object都有自己的name,这是我们混合编程的前提,至于它是怎么查找的我们下一节来扒。

    展开全文
  • Qt 是一个用标准 C++ 编写的跨平台开发类库,它对标准 C++ 进行了扩展,引入了元对象系统、信号与槽、属性等特性,使应用程序的开发变得更高效。 本节将介绍 Qt 的这些核心特点,对于理解和编写高效的 Qt C++ 程序是...

    Qt 是一个用标准 C++ 编写的跨平台开发类库,它对标准 C++ 进行了扩展,引入了元对象系统、信号与槽、属性等特性,使应用程序的开发变得更高效。

    本节将介绍 Qt 的这些核心特点,对于理解和编写高效的 Qt C++ 程序是大有帮助的。

    Qt 的元对象系统

    Qt 的元对象系统(Meta-Object System)提供了对象之间通信的信号与槽机制、运行时类型信息和动态属性系统。

    元对象系统由以下三个基础组成:

    1. QObject 类是所有使用元对象系统的类的基类。
    2. 在一个类的 private 部分声明 Q_OBJECT宏,使得类可以使用元对象的特性,如动态属性、信号与槽。
    3. MOC(元对象编译器)为每个 QObject 的子类提供必要的代码来实现元对象系统的特性。


    构建项目时,MOC 工具读取 C++ 源文件,当它发现类的定义里有 Q_OBJECT 宏时,它就会为这个类生成另外一个包含有元对象支持代码的 C++ 源文件,这个生成的源文件连同类的实现文件一起被编译和连接。

    除了信号与槽机制外,元对象还提供如下一些功能:

    • QObject::metaObject() 函数返回类关联的元对象,元对象类 QMetaObject 包含了访问元对象的一些接口函数,例如 QMetaObject::className() 函数可在运行时返回类的名称字符串。

      QObject *obj = new QPushButton;
      obj->metaObject()->className (); //返回"QPushButton"

    • QMetaObject::newInstance() 函数创建类的一个新的实例。
    • QObject::inherits(const char *className) 函数判断一个对象实例是否是名称为 className 的类或 QObject 的子类的实例。例如:

      QTimer *timer = new QTimer; // QTimer 是 QObject 的子类
      timer->inherits ("QTimer"); // 返回 true
      timer->inherits ("QObject");  // 返回 true
      timer->inherits ("QAbstractButton");//返回 false,不是 QAbstractButton 的子类

    • QObject::tr() 和 QObject::trUtf8() 函数可翻译字符串,用于多语言界面设计,后续章会专门介绍多语言界面设计。
    • QObject::setProperty() 和 QObject::property() 函数用于通过属性名称动态设置和获取属性值。


    对于 QObject 及其子类,还可以使用 qobject_cast() 函数进行动态投射(dynamic cast)。例如,假设 QMyWidget 是 QWidget 的子类并且在类定义中声明了 Q_OBJECT 宏。创建实例使用下面的语句:

    QObject *obj = new QMyWidget;

    变量 obj 定义为 QObject 指针,但它实际指向 QMyWidget 类,所以可以正确投射为 QWidget,即:

    QWidget *widget = qobject_cast<QWidget *>(obj);

    从 QObject 到 QWidget 的投射是成功的,因为 obj 实际是 QMyWidget 类,是 QWidget 的子类。也可以将其成功投射为 QMyWidget,即:

    QMyWidget *myWidget = qobject_cast<QMyWidget *>(obj);

    投射为 QMyWidget 是成功的,因为 qobject_cast() 并不区分 Qt 内建的类型和用户自定义类型。但是,若要将 obj 投射为 QLabel 则是失败的,即:

    QLabel * label - qobject_cast<QLabel *>(obj);

    这样投射是失败的,返回指针 label 为 NULL,因为 QMyWidget 不是 QLabel 的子类。

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

    属性系统

    属性定义

    Qt 提供一个 Q_PROPERTY() 宏可以定义属性,它也是基于元对象系统实现的。Qt 的属性系统与 C++ 编译器无关,可以用任何标准的 C++ 编译器编译定义了属性的 Qt C++ 程序。

    在 QObject 的子类中,用宏 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 表示所定义的属性不能被子类重载。


    QWidget 类定义属性的一些例子如下:

    Q_PROPERTY(bool focus READ hasFocus)
    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
    Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)

    属性的使用

    不管是否用 READ 和 WRITE 定义了接口函数,只要知道属性名称,就可以通过 QObject::property() 读取属性值,并通过 QObject::setProperty() 设置属性值。例如:

    QPushButton *button = new QPushButton;
    QObject *object = button;
    object->setProperty("flat", true);
    bool isFlat= object->property ("flat");

    动态属性

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

    动态属性可以使用 QObject::property() 查询,就如在类定义里用 Q_PROPERTY 宏定义的属性一样。

    例如,在数据表编辑界面上,一些字段是必填字段,就可以在初始化界面时为这些字段的关联显示组件定义一个新的 required 属性,并设置值为“true”,如:

    editName->setProperty("required", "true");
    comboSex->setProperty("required", "true");
    checkAgree->setProperty("required", "true");

    然后,可以应用下面的样式定义将这种必填字段的背景颜色设置为亮绿色。

    *[required="true"]{background-color:lime}

    类的附加信息

    属性系统还有一个宏 Q_CLASSINFO(),可以为类的元对象定义“名称——值”信息,如:

    class QMyClass:public QObject {
        Q_OBJECT
        Q_CLASSINFO("author", "Wang")
        Q_CLASSINFO ("company", "UPC")
        Q_CLASSINFO("version ", "3.0.1")
      public:
        ...
    };

    用 Q_CLASSINFO() 宏定义附加类信息后,可以通过元对象的一些函数获取类的附加信息,如 classlnfo(int) 获取某个附加信息,函数原型定义如下:

    QMetaClassInfo QMetaObject::classInfo(int index) const

    返回值是 QMetaClassInfo 类型,有 name() 和 value() 两个函数,可获得类附加信息的名称和值。

    展开全文
  • 解析Qt元对象系统(一) 概述

    千次阅读 2018-07-21 10:53:12
    Meta-Object System 提供了Qt的信号和槽机制以及对象之间的互相通信,运行时的信息和动态属性系统。 三个必要条件: 1. QObject的子类 2. 宏Q_OBJECT 3. Meta Object Compiler Qt官方建议对自定义的QObject子类...

    Meta-Object System 提供了Qt的信号和槽机制以及对象之间的互相通信,运行时的信息和动态属性系统。

    三个必要条件:
    1. QObject的子类
    2. 宏Q_OBJECT
    3. Meta Object Compiler

    Qt官方建议对自定义的QObject子类都要加这个宏,但要注意:某些类不是继承自QObject,这些类里加Q_OBJECT就会出错,例如QEvent,QGraphicsItem,QRunnable.

    MOC的实现是一个预处理器,使用MOC的方式,所有平台上的标准的C++编译器都能支持Qt。从而不需要实现一个新的跨平台的Qt编译器。moc是为了解决反射的问题,但是一些动态的编程语言(如Python,Ruby等)中,语言本身自带反射功能。Qt程序之所以编译速度慢,主要是因为在 Qt 将源代码交给标准C++编译器,如gcc之前,需要事先将这些扩展的语法去除掉。完成这一操作的就是 moc。

    如果工程是用qmake生成Makefile进行编译,那么其中就包含了调用moc的规则,我们不必直接使用moc.exe。moc.exe会读取头文件,查看是否有Q_OBJECT宏定义,如果有则根据这个头文件生成相应的moc_.cpp,该文件同样将进入编译系统,最终被链接到二进制代码中去,QtCreator生成的代码就是通过编译链接时,把moc_widget.o与其他目标文件链接到一起,这种方式不用改源代码,相对而言比较顺眼。

    moc_.cpp主要实现了头文件中的Q_OBJECT宏和SIGNAL,也就是将Qt扩展的语法去掉,再交给C++编译器。
    SIGNAL只在头文件做声明,但我们写Qt程序时从不进行实现,因为它是在moc_.cpp里实现的,
    例如无参数信号void Text();的实现:

    void MainWindow::Text()
    {
        QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
    }

    有参数信号void time(QDateTime t);的实现:

    void MainWindow::time(QDateTime _t1)
    {
        void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
        QMetaObject::activate(this, &staticMetaObject, 1, _a);
    }

    主要调用QMetaObject::activate方法,staticMetaObject是这个类默认的一个静态元对象。第三个参数是信号对应的序数。第四个参数如果是nullptr则代表信号无参数,否则代表参数的指针。

    moc文件也可以在cpp文件中被include,Qt官方示例很多就是这样做的,我们也可以这样写常见的MainWindow程序:

    #include <QApplication>
    #include <QMainWindow>
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    public:
        explicit MainWindow(QWidget *parent=0):
            QMainWindow(parent)
        {}
        ~MainWindow()
        {}
    };
    
    #include "main.moc"
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow m;
        m.resize(800,600);
        m.show();
        return a.exec();
    }

    编译之前先运行qmake,以处理宏Q_OBJECT,生成main.moc。如果没有#include "main.moc",会报错:
    无法解析3个外部符号,即moc文件中实现的3个函数:qt_metacall, qt_metacast, metaObject

    元对象系统涉及到的类: QMetaType, QMetaMethod, QMetaObject, QMataClassInfo, QMetaEnum, QMetaDataReaderControl, QMetaProperty,

    QMataType是Qt所支持的元类型,有个Type的枚举,这个枚举列表中的所有类型是Qt信号槽机制本身就支持的,大部分的类型实际在宏QT_FOR_EACH_STATIC_TYPE中包含。如果是自定义的类型需要用qRegisterMetaType去注册元类型才能被Qt的信号槽所识别。

    QMetaMethod有个重要的成员函数invoke,支持跨线程调用,是基于元对象系统的。

    QMetaObject是元对象类本身,实现了QMetaObject::invokeMethod, 功能和QMetaMethod没有什么区别。提供了元对象系统的基本方法,包括方法/信号槽/属性的数目/序数等等方法。

    QMataClassInfo提供了类的附加信息。

    元对象系统的一些常用工具:

    • QObject::metaObject(),返回当前类的元对象信息,是个QMetaObject指针;QObject::staticMetaObject也可以获取当前类的元对象信息,类型是QMetaObject。
    • QMetaObject::className(),运行时返回类名,返回类型是char*。
    • QMetaObject::newInstance(),构造一个新的实例。
    • QObject::inherits(),判断当前对象实例的类继承关系,常用于判断某个对象属于哪个类。
    • QObject::tr() 和QObject::trUtf8()用于Qt语言国际化,返回类型是QString。
    • QObject::property()/setProperty(),通过属性名动态获取/修改属性值。
    • qobject_cast(),动态类型转换,类似于标准C++的dynamic_cast(),不同的是它不需要RTTI(run time type information)且不受动态库的限制。
    展开全文
  • Qt元对象系统简介

    2020-06-01 19:20:58
    1、元对象系统简介 Qt 的信号槽和属性系统基于在运行时进行内省的能力,所谓内省是指面向对象语言的一种在运行期间查询对象信息的能力, 比如如果语言具有运行期间检查对象型别的能力,那么是型别内省(type ...
  • Qt元对象系统两个版本的介绍,The Meta-Object System (4.8) / The Meta-Object System (5.14),通过比对,她们的介绍几乎没有一丁点的不一致,描述如下, Qt’s meta-object system provides the signals and slots...
  • 目录 ...二、Qt元对象系统源码解析 1、Q_OBJECT宏的定义 2、QMetaObject类型 3、QT_TR_FUNCTIONS宏定义 4、Qt中其它宏的定义 三、对象编译器MOC 1、MOC功能 2、MOC限制 3、自定义类型...
  • Qt 元对象系统

    2021-04-09 14:07:36
    元对象系统(Meta-Object System)是Qt开发库中最重要的核心系统。元对象系统提供类对象之间通信的信号与槽机制、运行时类型信息和动态属性系统。 元对象系统由以下三部分组成: QObject:QObject类是所有使用...
  • 这也是大家讲Qt就必须将信号与槽,讲信号与槽就要讲Qt元对象系统。当然初学者知道怎么用就OK啦,当然随着你写的代码越多,接触的平台越多的时候,你就会好奇Qt是如何把两个(多个)任意不相关(必须都继承与...
  • 解析Qt元对象系统(三) 信号与槽

    千次阅读 2018-07-21 10:54:02
    引述 ...先运行一个普通的QWidget程序,添加一个按钮,定义一个槽函数test,函数体里做个断点,调试运行,...元对象系统的调用层次如下 QAbstractButtonPrivate::click和QAbstractButtonPrivate::emitClicked属于源...
  • Qt 是一个用标准 C++ 编写的跨平台开发类库,它对标准 C++ 进行了扩展,引入了元对象系统、信号与槽、属性等特性,使应用程序的开发变得更高效。 Qt对象编译器(MOC)是一个预处理器,在源程序被编译前先将Qt特性...
  • 解析Qt元对象系统(二) Q_OBJECT

    千次阅读 2018-07-21 10:53:37
    Q_OBJECT宏的定义在qobjectdefs.h: #define Q_OBJECT \ ... QT_WARNING_PUSH \ Q_OBJECT_NO_OVERRIDE_WARNING \ static const QMetaObject staticMetaObject; \ virtual const QMetaObject *met...
  • 我们在Qt源码中可以看到一个QObject的子类经常会用到一些Q_开头的宏,例如QMainWindow类开始部分代码是这样的: Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) Q_PROPERTY(Qt::ToolButtonStyle ...
  • Qt元对象系统

    2015-03-28 09:23:55
    Qt 元对象系统(Meta-Object System) Qt元对象系统基于如下三件事情: 1. 类:QObject,为所有需要利用元对象系统的对象提供了一个基类。 2. 宏:Q_OBJECT,通常可以声明在类的私有段中,让该类可以使用对象的...
  • Qt高级——Qt元对象系统源码解析 基于Qt4.8.6版本 一、Qt元对象系统简介 1、元对象系统简介 Qt 的信号槽和属性系统基于在运行时进行内省的能力,所谓内省是指面向对象语言的一种在运行期间查询对象信息的能力, ...
  • 之前的《Qt 元对象系统》大概介绍了Qt Meta-Object System(Qt元对象系统)的基本内容。 本文主要介绍元对象系统中的Meta-methods(方法): Meta-methods是什么? 列举Meta-methods 调用Meta-methods 测试Meta-...
  • Qt是一个用标准C++编写的跨平台开发类库,它对标准C++进行了扩展,引入了元对象系统、信号与槽、属性等特性,使应用程序的开发变得更高效。本章将开始介绍Qt的这些核心特点,对于理解和编写高效的QtC++程序是大有帮助...
  • 使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起。 Q_INVOKABLE与QMetaObject::invokeMethod均由元对象系统唤起。这一机制在Qt C++/QML混合编程,跨线程编程,Qt Service ...
  • 一、Qt元对象系统简介1、元对象系统简介Qt 的信号槽和属性系统基于在运行时进行内省的能力,所谓内省是指面向对象语言的一种在运行期间查询对象信息的能力, 比如如果语言具有运行期间检查对象型别的能力,那么是...
  • 元对象系统 动态投射 这样投射是失败的,返回指针label为NULL,因为QMyWidget不是QLabel的子类。 使用动态投射,使得程序可以在运行时对不同的对象做不同的处理。 属性系统 两个宏 Q_PROPERTY(),基于...
  • Qt添加C++原本不具备的元对象系统元对象系统提供了信号槽机制,运行时类型信息和动态属性系统。 元对象系统基于三点: 1.元对象系统为以QObject类为基类的对象提供了特有的功能 2.类private的Q_OBJECT宏使得...
  • QT元对象系统简介

    2016-06-05 10:00:26
    QT元对象系统 qt的主要成就之一就是使用了一种机制对C++进行了扩展,并且使用这种机制创建了独立的软件组件,这些组件可以绑定在一起,但任何一个组件对于它所要连接的组件的情况一无所知,这种机制就称为元对象...
  • 目录为什么Qt将Moc用于信号和插槽?语法的重要性代码生成器很好用GUI是动态的调用性能并非一切没有限制 为什么Qt将Moc用于信号和插槽?   模板是C ++中的内置机制,允许编译器动态生成代码,具体取决于传递的参数...
  • 对象是指用于描述另一个对象结构的对象。使用编程语言具体实现时,其实就是一个类的对象,只不过这个对象...元对象系统Qt 对原有的 C++进行的一些扩展,主要是为实现信号和槽机制而引入的,信号和槽机制是 Qt...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,215
精华内容 4,886
关键字:

qt元对象系统详解