Inside QT Series (三):元对象系统(Meta-Object System)
2012-09-10 11:20
267 查看
从本节开始,我们讲解 QT Meta-Object System 的功能,以及实现。
在使用 QT 开发的过程中,大量的使用了 signal 和 slot. 比如,响应一个 button 的 click 事件,我们一般都写如下的代码:
class MyWindow : public QWidget
{
Q_OBJECT
public:
MyWindow(QWidget* parent) : QWidget(parent)
{
QPushButton* btnStart = new QPushButton(“start”, this);
connect(btnStart, SIGNAL(clicked()), SLOT(slotStartClicked()));
}
private slots:
void slotStartClicked();
};
void MyWindow:: slotStartClicked()
{
// 省略
}
在这段代码中,我们把 btnStart 这个 button 的clicked() 信号和 MyWindow 的 slotStartClicked() 这个槽相连接,当 btnStart 这个 button 被用户按下(click)的时候,就会发出一个 clicked() 的信号,然后,MyWindow:: slotStartClicked() 这个 slot 函数就会被调用用来响应 button 的 click 事件。
这段代码是最为典型的 signal/slot 的应用实例,在实际的工作过程中,signal/slot 还有更为广泛的应用。准确的说,signal/slot 是QT提供的一种在对象间进行通讯的技术,那么,这个技术在QT 中是如何实现的呢?
这就是 QT 中的元对象系统(Meta Object System)的作用,为了更好的理解它,让我先来对它的功能做一个回顾,让我们一起来揭开它神秘的面纱。
Meta-Object System 的基本功能
Meta Object System 的设计基于以下几个基础设施:
QObject 类
作为每一个需要利用元对象系统的类的基类
Q_OBJECT 宏,
定义在每一个类的私有数据段,用来启用元对象功能,比如,动态属性,信号和槽
元对象编译器moc (the Meta Object Complier),
moc 分析C++源文件,如果它发现在一个头文件(header file)中包含Q_OBJECT 宏定义,然后动态的生成另外一个C++源文件,这个新的源文件包含 Q_OBJECT 的实现代码,这个新的 C++ 源文件也会被编译、链接到这个类的二进制代码中去,因为它也是这个类的完整的一部分。通常,这个新的C++ 源文件会在以前的C++ 源文件名前面加上 moc_ 作为新文件的文件名。其具体过程如下图所示:
除了提供在对象间进行通讯的机制外,元对象系统还包含以下几种功能:
QObject::metaObject() 方法
它获得与一个类相关联的 meta-object
QMetaObject::className() 方法
在运行期间返回一个对象的类名,它不需要本地C++编译器的RTTI(run-time type information)支持
QObject::inherits() 方法
它用来判断生成一个对象类是不是从一个特定的类继承出来,当然,这必须是在QObject类的直接或者间接派生类当中
QObject::tr() and QObject::trUtf8()
这两个方法为软件的国际化翻译字符串
QObject::setProperty() and QObject::property()
这两个方法根据属性名动态的设置和获取属性值
除了以上这些功能外,它还使用qobject_cast()方法在QObject类之间提供动态转换,qobject_cast()方法的功能类似于标准C++的dynamic_cast(),但是qobject_cast()不需要RTTI的支持,
在一个QObject类或者它的派生类中,我们可以不定义Q_OBJECT宏。如果我们在一个类中没有定义Q_OBJECT宏,那么在这里所提到的相应的功能在这个类中也不能使用,从meta-object的观点来说,一个没有定义Q_OBJECT宏的类与它最接近的那个祖先类是相同的,那就是所,QMetaObject::className() 方法所返回的名字并不是这个类的名字,而是与它最接近的那个祖先类的名字。所以,我们强烈建议,任何从QObject继承出来的类都定义Q_OBJECT宏。
下一节,我们来了解另一个重要的工具:Meta-Object Compiler
在使用 QT 开发的过程中,大量的使用了 signal 和 slot. 比如,响应一个 button 的 click 事件,我们一般都写如下的代码:
class MyWindow : public QWidget
{
Q_OBJECT
public:
MyWindow(QWidget* parent) : QWidget(parent)
{
QPushButton* btnStart = new QPushButton(“start”, this);
connect(btnStart, SIGNAL(clicked()), SLOT(slotStartClicked()));
}
private slots:
void slotStartClicked();
};
void MyWindow:: slotStartClicked()
{
// 省略
}
在这段代码中,我们把 btnStart 这个 button 的clicked() 信号和 MyWindow 的 slotStartClicked() 这个槽相连接,当 btnStart 这个 button 被用户按下(click)的时候,就会发出一个 clicked() 的信号,然后,MyWindow:: slotStartClicked() 这个 slot 函数就会被调用用来响应 button 的 click 事件。
这段代码是最为典型的 signal/slot 的应用实例,在实际的工作过程中,signal/slot 还有更为广泛的应用。准确的说,signal/slot 是QT提供的一种在对象间进行通讯的技术,那么,这个技术在QT 中是如何实现的呢?
这就是 QT 中的元对象系统(Meta Object System)的作用,为了更好的理解它,让我先来对它的功能做一个回顾,让我们一起来揭开它神秘的面纱。
Meta-Object System 的基本功能
Meta Object System 的设计基于以下几个基础设施:
QObject 类
作为每一个需要利用元对象系统的类的基类
Q_OBJECT 宏,
定义在每一个类的私有数据段,用来启用元对象功能,比如,动态属性,信号和槽
元对象编译器moc (the Meta Object Complier),
moc 分析C++源文件,如果它发现在一个头文件(header file)中包含Q_OBJECT 宏定义,然后动态的生成另外一个C++源文件,这个新的源文件包含 Q_OBJECT 的实现代码,这个新的 C++ 源文件也会被编译、链接到这个类的二进制代码中去,因为它也是这个类的完整的一部分。通常,这个新的C++ 源文件会在以前的C++ 源文件名前面加上 moc_ 作为新文件的文件名。其具体过程如下图所示:
除了提供在对象间进行通讯的机制外,元对象系统还包含以下几种功能:
QObject::metaObject() 方法
它获得与一个类相关联的 meta-object
QMetaObject::className() 方法
在运行期间返回一个对象的类名,它不需要本地C++编译器的RTTI(run-time type information)支持
QObject::inherits() 方法
它用来判断生成一个对象类是不是从一个特定的类继承出来,当然,这必须是在QObject类的直接或者间接派生类当中
QObject::tr() and QObject::trUtf8()
这两个方法为软件的国际化翻译字符串
QObject::setProperty() and QObject::property()
这两个方法根据属性名动态的设置和获取属性值
除了以上这些功能外,它还使用qobject_cast()方法在QObject类之间提供动态转换,qobject_cast()方法的功能类似于标准C++的dynamic_cast(),但是qobject_cast()不需要RTTI的支持,
在一个QObject类或者它的派生类中,我们可以不定义Q_OBJECT宏。如果我们在一个类中没有定义Q_OBJECT宏,那么在这里所提到的相应的功能在这个类中也不能使用,从meta-object的观点来说,一个没有定义Q_OBJECT宏的类与它最接近的那个祖先类是相同的,那就是所,QMetaObject::className() 方法所返回的名字并不是这个类的名字,而是与它最接近的那个祖先类的名字。所以,我们强烈建议,任何从QObject继承出来的类都定义Q_OBJECT宏。
下一节,我们来了解另一个重要的工具:Meta-Object Compiler
相关文章推荐
- Qt Meta Object System-元对象系统
- Inside QT Series (五):元对象系统(Meta-Object System)
- Inside Qt Series (八):Meta Object Class overview
- Inside QT Series (六):元对象编译器 - Meta Object Compiler (moc)
- Inside Qt Series (五):元对象系统(Meta-Object System)
- Inside Qt Series (九):QMetaObject class data members
- Inside Qt Series (六):元对象编译器 – Meta Object Compiler (moc)
- Qt Meta Object System-元对象系统
- Inside QT Series (八):Meta Object Class
- Inside Qt Series (五):元对象系统(Meta-Object System)
- Inside Qt Series (八):Meta Object Class overview
- Inside Qt Series (九):QMetaObject class data members
- Inside QT Series (九):QMetaObject class data members
- Inside Qt Series (九):QMetaObject class data members
- Changes to the Meta-Object System in Qt 5
- Qt MetaObject System详解
- Qt MetaObject System详解之二:meta数据和数据结构
- Qt MetaObject System详解之四:meta call
- Qt MetaObject System-- 元对象系统
- Qt Meta Object system 学习(一)