现在的位置: 首页 > 综合 > 正文

Qt ObjectModel (from Qt doc)

2012年04月10日 ⁄ 综合 ⁄ 共 5817字 ⁄ 字号 评论关闭

这里面讲了Qt 的类图root: QObject的一些信息。

Wentao Sun.

Qt Object model

The standard C++ object model provides very efficient runtime support for the object paradigm. But its static nature is inflexibile in certain problem domains. Graphical user interface programming is a domain that requires both runtime efficiency and a high level of flexibility. Qt provides this, by combining the speed of C++ with the flexibility of the Qt Object Model.

Qt adds these features to C++:

  • a very powerful mechanism for seamless object communication called signals and slots
  • queryable and designable object properties
  • powerful events and event filters
  • contextual string translation for internationalization
  • sophisticated interval driven timers that make it possible to elegantly integrate many tasks in an event-driven GUI
  • hierarchical and queryable object trees that organize object ownership in a natural way
  • guarded pointers (QPointer) that are automatically set to 0 when the referenced object is destroyed, unlike normal C++ pointers which become dangling pointers when their objects are destroyed
  • a dynamic cast that works across library boundaries.

Many of these Qt features are implemented with standard C++ techniques, based on inheritance from QObject. Others, like the object communication mechanism and the dynamic property system, require the Meta-Object System provided by Qt's own Meta-Object Compiler (moc).

The meta-object system is a C++ extension that makes the language better suited to true component GUI programming. Although templates can be used to extend C++, the meta-object system provides benefits using standard C++ that cannot be achieved with templates.

 

 Detailed Description

The QObject class is the base class of all Qt objects.

QObject is the heart of the Qt object model. The central feature in this model is a very powerful mechanism for seamless object communication called signals and slots. You can connect a signal to a slot with connect() and destroy the connection with disconnect(). To avoid never ending notification loops you can temporarily block signals with blockSignals(). The protected functions connectNotify() and disconnectNotify() make it possible to track connections.

QObjects organize themselves in object trees. When you create a QObject with another object as parent, the object will automatically add itself to the parent's children() list. The parent takes ownership of the object i.e. it will automatically delete its children in its destructor. You can look for an object by name and optionally type using findChild() or findChildren().

Every object has an objectName() and its class name can be found via the corresponding metaObject() (see QMetaObject::className()). You can determine whether the object's class inherits another class in the QObject inheritance hierarchy by using the inherits() function.

When an object is deleted, it emits a destroyed() signal. You can catch this signal to avoid dangling references to QObjects.

QObjects can receive events through event() and filter the events of other objects. See installEventFilter() and eventFilter() for details. A convenience handler, childEvent(), can be reimplemented to catch child events.

Events are delivered in the thread in which the object was created; see Thread Support in Qt and thread() for details. Note that event processing is not done at all for QObjects with no thread affinity (thread() returns zero). Use the moveToThread() function to change the thread affinity for an object and its children (the object cannot be moved if it has a parent).

Last but not least, QObject provides the basic timer support in Qt; see QTimer for high-level support for timers.

Notice that the Q_OBJECT macro is mandatory for any object that implements signals, slots or properties. You also need to run the Meta Object Compiler on the source file. We strongly recommend the use of this macro in all subclasses of QObject regardless of whether or not they actually use signals, slots and properties, since failure to do so may lead certain functions to exhibit strange behavior.

All Qt widgets inherit QObject. The convenience function isWidgetType() returns whether an object is actually a widget. It is much faster than qobject_cast<QWidget *>(obj) or obj->inherits("QWidget").

Some QObject functions, e.g. children(), return a QObjectList. QObjectList is a typedef for QList<QObject *>.

 

 Implicitly Shared Classes

Many C++ classes in Qt use implicit data sharing to maximize resource usage and minimize copying. Implicitly shared classes are both safe and efficient when passed as arguments, because only a pointer to the data is passed around, and the data is copied only if and when a function writes to it, i.e., copy-on-write.

  • Overview
  • Implicit Sharing in Detail
  • List of Classes

Overview

A shared class consists of a pointer to a shared data block that contains a reference count and the data.

When a shared object is created, it sets the reference count to 1. The reference count is incremented whenever a new object references the shared data, and decremented when the object dereferences the shared data. The shared data is deleted when the reference count becomes zero.

When dealing with shared objects, there are two ways of copying an object. We usually speak about deep and shallow copies. A deep copy implies duplicating an object. A shallow copy is a reference copy, i.e. just a pointer to a shared data block. Making a deep copy can be expensive in terms of memory and CPU. Making a shallow copy is very fast, because it only involves setting a pointer and incrementing the reference count.

Object assignment (with operator=()) for implicitly shared objects is implemented using shallow copies.

The benefit of sharing is that a program does not need to duplicate data unnecessarily, which results in lower memory use and less copying of data. Objects can easily be assigned, sent as function arguments, and returned from functions.

Implicit sharing takes place behind the scenes; the programmer does not need to worry about it. Even in multithreaded applications, implicit sharing takes place, as explained in Threads and Implicit Sharing.

Implicit Sharing in Detail

Implicit sharing automatically detaches the object from a shared block if the object is about to change and the reference count is greater than one. (This is often called copy-on-write or value semantics.)

An implicitly shared class has total control of its internal data. In any member functions that modify its data, it automatically detaches before modifying the data.

The QPen class, which uses implicit sharing, detaches from the shared data in all member functions that change the internal data.

Code fragment:

 void QPen::setStyle(Qt::PenStyle style)
 {
     detach();           // detach from common data
     d->style = style;   // set the style member
 }
 void QPen::detach()
 {
     if (d->ref != 1) {
         ...             // perform a deep copy
     }
 } 

抱歉!评论已关闭.