“深入浅出”系列之QT:(14)Qt元对象系统介绍
- 其他
- 2025-09-20 02:03:02

1. 前言:Qt的核心特点与全局定义
Qt是一个用标准C++编写的跨平台开发类库,它对标准C++进行了扩展,引入了元对象系统、信号与槽、属性等特性,使应用程序的开发变得更高效。本章将介绍Qt的这些核心特点,并深入探讨**<QtGlobal>头文件**中的全局定义,包括数据类型、函数和宏等。此外,本章还将介绍Qt的容器类及其迭代器的使用方法。这些全局定义和容器类在程序中经常用到,了解其原理有助于理解后续的实例程序。
2. 正文概述:Qt的核心机制 2.1 Qt的本质与扩展Qt本身并不是一种编程语言,而是一个跨平台的C++开发类库。它为开发GUI应用程序和非GUI应用程序提供了各种类。Qt对标准C++进行了扩展,引入了信号与槽、对象属性等新概念和功能。
2.2 元对象编译器(MOC)Qt的元对象编译器(Meta-Object Compiler,MOC)是一个预处理器,它在源程序被编译前,将Qt特性的程序转换为标准C++兼容的形式,然后再由标准C++编译器进行编译。这就是为什么在使用信号与槽机制的类中,必须添加Q_OBJECT宏的原因。只有添加了这个宏,MOC才能对类里的信号与槽代码进行预处理。
2.3 QtCore模块QtCore模块是Qt类库的核心,所有其他模块都依赖于此模块。如果使用qmake来构建项目,QtCore模块会自动加入。Qt为C++语言增加的特性就是在QtCore模块里实现的,这些扩展特性由Qt的元对象系统实现,包括信号与槽机制、属性系统、动态类型转换等。
3. 什么是元对象系统 3.1 元对象系统的基础组成Qt的元对象系统(Meta-Object System)提供了对象之间通信的信号与槽机制、运行时类型信息和动态属性系统。元对象系统由以下三个基础组成:
QObject类:所有使用元对象系统的类的基类。
Q_OBJECT宏:在类的private部分声明该宏,使得类可以使用元对象的特性,如动态属性、信号与槽。
MOC(元对象编译器):为每个QObject的子类提供必要的代码来实现元对象系统的特性。
3.2 元对象系统的功能除了信号与槽机制外,元对象系统还提供以下功能:
QObject::metaObject():返回类关联的元对象,元对象类QMetaObject包含了访问元对象的一些接口函数。
QMetaObject::newInstance():创建类的一个新实例。
QObject::inherits():判断一个对象实例是否是某个类或其子类的实例。
QObject::tr()和QObject::trUtf8():用于多语言界面设计的字符串翻译。
QObject::setProperty()和QObject::property():通过属性名称动态设置和获取属性值。
4. 元对象特性案例讲解 4.1 QPerson类的定义以下是一个演示Qt元对象系统功能的实例。首先,我们创建一个类QPerson,其定义如下:
class QPerson : public QObject { Q_OBJECT Q_CLASSINFO("author", "Wang") Q_CLASSINFO("company", "UPC") Q_CLASSINFO("version", "1.0.0") Q_PROPERTY(int age READ age WRITE setAge NOTIFY ageChanged) Q_PROPERTY(QString name MEMBER m_name) Q_PROPERTY(int score MEMBER m_score) private: int m_age = 10; QString m_name; int m_score = 79; public: explicit QPerson(QString fName, QObject *parent = nullptr); int age(); void setAge(int value); void incAge(); signals: void ageChanged(int value); public slots: };QPerson是QObject的子类,使用了Q_OBJECT宏,因此它获得了元对象系统的支持,能够使用信号与槽、属性等功能。
4.2 QPerson类的实现 QPerson::QPerson(QString fName, QObject *parent) : QObject(parent) { m_name = fName; } int QPerson::age() { return m_age; } void QPerson::setAge(int value) { m_age = value; emit ageChanged(m_age); } void QPerson::incAge() { m_age++; emit ageChanged(m_age); }在**setAge(int)函数中,设置年龄后会发射ageChanged()**信号。**incAge()函数与属性无关,但也会发射ageChanged()**信号。
5. 元对象特性使用详解 5.1 QmyWidget类的定义主窗口是基于QWidget的可视化设计的类QmyWidget,其定义如下:
class QmyWidget : public QWidget { Q_OBJECT private: QPerson *boy; QPerson *girl; public: explicit QmyWidget(QWidget *parent = 0); ~QmyWidget(); private: Ui::QmyWidget *ui; private slots: void on_ageChanged(int value); void on_spin_valueChanged(int arg1); void on_btnClear_clicked(); void on_btnBoyInc_clicked(); void on_btnGirlInc_clicked(); void on_btnClassInfo_clicked(); }; 5.2 QmyWidget类的实现在构造函数中,我们创建了两个QPerson类型的对象boy和girl,并设置了它们的属性:
QmyWidget::QmyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::QmyWidget) { ui->setupUi(this); boy = new QPerson("王小明"); boy->setProperty("score", 95); boy->setProperty("age", 10); boy->setProperty("sex", "Boy"); // 动态属性 connect(boy, &QPerson::ageChanged, this, &QmyWidget::on_ageChanged); girl = new QPerson("张小丽"); girl->setProperty("score", 81); girl->setProperty("age", 20); girl->setProperty("sex", "Girl"); // 动态属性 connect(girl, &QPerson::ageChanged, this, &QmyWidget::on_ageChanged); ui->spinBoy->setProperty("isBoy", true); // 动态属性 ui->spinGirl->setProperty("isBoy", false); connect(ui->spinGirl, SIGNAL(valueChanged(int)), this, SLOT(on_spin_valueChanged(int))); connect(ui->spinBoy, SIGNAL(valueChanged(int)), this, SLOT(on_spin_valueChanged(int))); } 5.3 自定义槽函数的实现自定义槽函数on_ageChanged()用于响应QPerson的**ageChanged()**信号:
void QmyWidget::on_ageChanged(int value) { Q_UNUSED(value); QPerson *aPerson = qobject_cast<QPerson *>(sender()); QString hisName = aPerson->property("name").toString(); QString hisSex = aPerson->property("sex").toString(); int hisAge = aPerson->age(); ui->textEdit->appendPlainText(hisName + "," + hisSex + QString::asprintf(",年龄=%d", hisAge)); } 5.4 元对象信息的获取通过**boy->metaObject()**获取对象的元对象信息,并显示在界面上:
void QmyWidget::on_btnClassInfo_clicked() { const QMetaObject *meta = boy->metaObject(); ui->textEdit->clear(); ui->textEdit->appendPlainText("==元对象信息==\n"); ui->textEdit->appendPlainText(QString("类名称: %1\n").arg(meta->className())); ui->textEdit->appendPlainText("property"); for (int i = meta->propertyOffset(); i < meta->propertyCount(); i++) { QMetaProperty prop = meta->property(i); const char *propName = prop.name(); QString propValue = boy->property(propName).toString(); ui->textEdit->appendPlainText(QString("属性名称=%1,属性值=%2").arg(propName).arg(propValue)); } ui->textEdit->appendPlainText("classInfo"); for (int i = meta->classInfoOffset(); i < meta->classInfoCount(); ++i) { QMetaClassInfo classInfo = meta->classInfo(i); ui->textEdit->appendPlainText(QString("Name=%1; Value=%2").arg(classInfo.name()).arg(classInfo.value())); } } 6. 总结通过本文的介绍,我们了解了Qt的元对象系统及其核心功能,包括信号与槽机制、属性系统、动态类型转换等。我们还通过QPerson和QmyWidget类的实例,详细讲解了如何使用元对象系统的特性。希望这些内容能帮助你更好地理解和编写高效的Qt C++程序。
“深入浅出”系列之QT:(14)Qt元对象系统介绍由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处““深入浅出”系列之QT:(14)Qt元对象系统介绍”