The Meta-Object System(Qt元对象系统)

Qt’s meta-object system provides the signals and slots mechanism for inter-object communication, run-time type information, and the dynamic property system.

Qt元对象系统提供内建对象通信的信号和槽机制,运行时类信息,和动态属性系统。

 

The meta-object system is based on three things:

元对象系统基于三样东西:

 

1.The QObject class provides a base class for objects that can take advantage of the meta-object system.

1.QObject类是对象的基类,可以利用元对象系统的优势。

 

 

2.The Q_OBJECT macro inside the private section of the class declaration is used to enable meta-object features, such as dynamic properties, signals, and slots.

Q_OBJECT宏在类的私有区声明,用来使用元对象的功能,例如:动态属性,信号和槽。

 

3.The Meta-Object Compiler (moc) supplies each QObject subclass with the necessary code to implement meta-object features.

元对象编译器(moc)为每个QObject子类提供必要的代码,使得其实现元对象的功能。

 

 

The moc tool reads a C++ source file. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces another C++ source file which contains the meta-object code for each of those classes. This generated source file is either #include'd into the class's source file or, more usually, compiled and linked with the class's implementation

 

moc工具读取C++源文件。如果它发现一个或多个包含Q_OBJECT宏的类声明,它将为那些类产生一个包含了元对象代码的C++源文件。生成的文件包含d(#include'd,什么鬼)至类的源文件,还有,类的实现的编译和链接。

 

 

In addition to providing the signals and slots mechanism for communication between objects (the main reason for introducing the system), the meta-object code provides the following additional features:

除了为对象间提供信号和槽通信机制外(介绍系统的主要原因),元对象代码还提供以下额外功能:

 

 

QObject::metaObject() returns the associated meta-object for the class.

QObject::metaObject()返回类的相关联元对象。

 

QMetaObject::className() returns the class name as a string at run-time, without requiring native run-time type information (RTTI) support through the C++ compiler.

QMetaObject::className()在运行时返回字符串类名,无需本地运行时类信息(RTTI)支持C++编译器。

 

QObject::inherits() function returns whether an object is an instance of a class that inherits a specified class within the QObject inheritance tree.

QObject::inherits()函数返回一个对象是否是在QObject继承树中指定类的派生类的实例。

 

QObject::tr() and QObject::trUtf8() translate strings for internationalization.

QObject::tr()和QObject::trUtf8()翻译字符串以实现国际化。

 

QObject::setProperty() and QObject::property() dynamically set and get properties by name.

QObject::setProperty()和QObject::property()通过名字动态地设置和获得属性。

 

QMetaObject::newInstance() constructs a new instance of the class.

QMetaObject::newInstance()构造类的新实例。

 

It is also possible to perform dynamic casts using qobject_cast() on QObject classes. The qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries. It attempts to cast its argument to the pointer type specified in angle-brackets, returning a non-zero pointer if the object is of the correct type (determined at run-time), or 0 if the object's type is incompatible.

另外也可以使用qobject_cast()执行QObject类之间的动态转换。qobject_cast()函数的行为类似标准C++的 dynamic_cast(),优势是它无需RTTI的支持并且可以跨动态库工作。它视图将参数转换成括号中指定类型的指针,如果对象是正确类型(在运行时确定的)返回非0指针,如果对象类型不符,返回0。

 

For example, let's assume MyWidget inherits from QWidget and is declared with the Q_OBJECT macro:

例如,让我们假设MyWidget继承于QWidget并且使用Q_OBJECT宏声明:

 

QObject *obj = new MyWidget;

 

The obj variable, of type QObject *, actually refers to a MyWidget object, so we can cast it appropriately:

变量obj是QObject类型指针,实际上它指向MyWidget对象,所以我们可以适当转换它:

 

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

 

The cast from QObject to QWidget is successful, because the object is actually a MyWidget, which is a subclass of QWidget. Since we know that obj is a MyWidget, we can also cast it to MyWidget *:

从QObject到QWidget的转换是成功的,因为对象实际是MyWidget(QWidget的子类)。因为我们知道对象MyWidget,所以我们可以将它转换成MyWidget*:

 

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

 

The cast to MyWidget is successful because qobject_cast() makes no distinction between built-in Qt types and custom types.

转换成MyWidget是成功的,因为qobject_cast()使内置的Qt类型和自定义类型之间没有区别。

 

 

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

//label is 0

 

The cast to QLabel, on the other hand, fails. The pointer is then set to 0. This makes it possible to handle objects of different types differently at run-time, based on the type:

另外转换成QLabel失败,指针会被设置为0。这使得可能在运行时以不同的方式处理不同类型的对象,基于类型:

 

if(QLabel* label = qobject_cast<QLabel*>(obj))

{

label->setText(tr("Ping"));

}

else if(QPushButton* button = qobject_cast<QPushButton*>(obj))

{

button->setText(tr("Poing!"));

}

 

While it is possible to use QObject as a base class without the Q_OBJECT macro and without meta-object code, neither signals and slots nor the other features described here will be available if the Q_OBJECT macro is not used. From the meta-object system's point of view, a QObject subclass without meta code is equivalent to its closest ancestor with meta-object code. This means for example, that QMetaObject::className() will not return the actual name of your class, but the class name of this ancestor.

尽管可以使用无Q_OBJECT声明和无元对象代码的QObject类作为基类,但如果不使用Q_OBJECT宏信号和槽不可使用,这里描述的其他功能也不能使用。从元对象系统的角度看,一个QObject子类没有元代码就相当于它最近的有元对象代码的祖先。这就意味着,例如:QMetaObject::className()不会返回类的实际的名字而是祖先的类名。

 

Therefore, we strongly recommend that all subclasses of QObject use the Q_OBJECT macro regardless of whether or not they actually use signals, slots, and properties.

所以我们强烈建议所有的QObject的子类中使用Q_OBJECT宏而不管它实际是否使用信号,槽和属性。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值