diff options
Diffstat (limited to 'src/declarative/qml')
-rw-r--r-- | src/declarative/qml/qdeclarativecontext.cpp | 7 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine.cpp | 79 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeerror.cpp | 51 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeextensionplugin.cpp | 11 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeimageprovider.cpp | 22 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeimageprovider.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativelist.cpp | 15 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeproperty.cpp | 1 |
8 files changed, 119 insertions, 69 deletions
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 6657fea..5288923 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -114,7 +114,7 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate() \endcode All properties added explicitly by QDeclarativeContext::setContextProperty() take - precedence over context object's properties. + precedence over the context object's properties. Contexts form a hierarchy. The root of this heirarchy is the QDeclarativeEngine's \l {QDeclarativeEngine::rootContext()}{root context}. A component instance can @@ -140,6 +140,11 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate() While QML objects instantiated in a context are not strictly owned by that context, their bindings are. If a context is destroyed, the property bindings of outstanding QML objects will stop evaluating. + + \note Setting the context object or adding new context properties after an object + has been created in that context is an expensive operation (essentially forcing all bindings + to reevaluate). Thus whenever possible you should complete "setup" of the context + before using it to create any objects. */ /*! \internal */ diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 76cd810..4dbd199 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -390,8 +390,6 @@ void QDeclarativeEnginePrivate::init() qmlEngineDebugServer(); isDebugging = true; QDeclarativeEngineDebugServer::addEngine(q); - - qmlEngineDebugServer()->waitForClients(); } } @@ -957,7 +955,7 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QS Q_ASSERT(context); if(ctxt->argumentCount() != 1) { - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 1 parameter")); }else{ QString arg = ctxt->argument(0).toString(); if (arg.isEmpty()) @@ -977,7 +975,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS QDeclarativeEngine* activeEngine = activeEnginePriv->q_func(); if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 2 or 3 parameters")); QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); Q_ASSERT(context); @@ -997,35 +995,30 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1)); if(!parentArg) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("parent object not found")); QDeclarativeComponent component(activeEngine); component.setData(qml.toUtf8(), url); if(component.isError()) { QList<QDeclarativeError> errors = component.errors(); - qWarning().nospace() << "QDeclarativeEngine::createQmlObject():"; + QString errstr = QLatin1String("Qt.createQmlObject(): "); foreach (const QDeclarativeError &error, errors) - qWarning().nospace() << " " << error; - - return engine->nullValue(); + errstr += QLatin1String(" ") + error.toString() + QLatin1String("\n"); + return ctxt->throwError(errstr); } - if (!component.isReady()) { - qWarning().nospace() << "QDeclarativeEngine::createQmlObject(): Component is not ready"; - - return engine->nullValue(); - } + if (!component.isReady()) + return ctxt->throwError(QDeclarativeEngine::tr("Qt.createQmlObject(): component is not ready")); QObject *obj = component.create(context->asQDeclarativeContext()); if(component.isError()) { QList<QDeclarativeError> errors = component.errors(); - qWarning().nospace() << "QDeclarativeEngine::createQmlObject():"; + QString errstr = QLatin1String("Qt.createQmlObject(): "); foreach (const QDeclarativeError &error, errors) - qWarning().nospace() << " " << error; - - return engine->nullValue(); + errstr += QLatin1String(" ") + error.toString() + QLatin1String("\n"); + return ctxt->throwError(errstr); } Q_ASSERT(obj); @@ -1051,7 +1044,7 @@ QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScript QScriptValue QDeclarativeEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 3) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 3 parameters")); qsreal x = ctxt->argument(0).toNumber(); qsreal y = ctxt->argument(1).toNumber(); qsreal z = ctxt->argument(2).toNumber(); @@ -1062,7 +1055,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptE { int argCount = ctxt->argumentCount(); if(argCount == 0 || argCount > 2) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 1 or 2 parameters")); QDate date = ctxt->argument(0).toDateTime().date(); Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; @@ -1073,7 +1066,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptE } else if (ctxt->argument(1).isNumber()) { enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32()); } else - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("invalid date format")); } return engine->newVariant(qVariantFromValue(date.toString(enumFormat))); } @@ -1082,7 +1075,7 @@ QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptE { int argCount = ctxt->argumentCount(); if(argCount == 0 || argCount > 2) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 1 or 2 parameters")); QTime date = ctxt->argument(0).toDateTime().time(); Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; @@ -1093,7 +1086,7 @@ QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptE } else if (ctxt->argument(1).isNumber()) { enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32()); } else - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("invalid time format")); } return engine->newVariant(qVariantFromValue(date.toString(enumFormat))); } @@ -1102,7 +1095,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr { int argCount = ctxt->argumentCount(); if(argCount == 0 || argCount > 2) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 1 or 2 parameters")); QDateTime date = ctxt->argument(0).toDateTime(); Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; @@ -1113,7 +1106,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr } else if (ctxt->argument(1).isNumber()) { enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32()); } else - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("invalid datetiem format")); } return engine->newVariant(qVariantFromValue(date.toString(enumFormat))); } @@ -1122,14 +1115,20 @@ QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine { int argCount = ctxt->argumentCount(); if(argCount < 3 || argCount > 4) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 3 or 4 parameters")); qsreal r = ctxt->argument(0).toNumber(); qsreal g = ctxt->argument(1).toNumber(); qsreal b = ctxt->argument(2).toNumber(); qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1; - if (r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1 || a < 0 || a > 1) - return engine->nullValue(); + if (r < 0.0) r=0.0; + if (r > 1.0) r=1.0; + if (g < 0.0) g=0.0; + if (g > 1.0) g=1.0; + if (b < 0.0) b=0.0; + if (b > 1.0) b=1.0; + if (a < 0.0) a=0.0; + if (a > 1.0) a=1.0; return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromRgbF(r, g, b, a))); } @@ -1138,14 +1137,20 @@ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine { int argCount = ctxt->argumentCount(); if(argCount < 3 || argCount > 4) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 3 or 4 parameters")); qsreal h = ctxt->argument(0).toNumber(); qsreal s = ctxt->argument(1).toNumber(); qsreal l = ctxt->argument(2).toNumber(); qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1; - if (h < 0 || h > 1 || s < 0 || s > 1 || l < 0 || l > 1 || a < 0 || a > 1) - return engine->nullValue(); + if (h < 0.0) h=0.0; + if (h > 1.0) h=1.0; + if (s < 0.0) s=0.0; + if (s > 1.0) s=1.0; + if (l < 0.0) l=0.0; + if (l > 1.0) l=1.0; + if (a < 0.0) a=0.0; + if (a > 1.0) a=1.0; return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromHslF(h, s, l, a))); } @@ -1153,7 +1158,7 @@ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 4) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 4 parameters")); qsreal x = ctxt->argument(0).toNumber(); qsreal y = ctxt->argument(1).toNumber(); @@ -1169,7 +1174,7 @@ QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 2) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 2 parameters")); qsreal x = ctxt->argument(0).toNumber(); qsreal y = ctxt->argument(1).toNumber(); return qScriptValueFromValue(engine, qVariantFromValue(QPointF(x, y))); @@ -1178,7 +1183,7 @@ QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngin QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 2) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 2 parameters")); qsreal w = ctxt->argument(0).toNumber(); qsreal h = ctxt->argument(1).toNumber(); return qScriptValueFromValue(engine, qVariantFromValue(QSizeF(w, h))); @@ -1187,7 +1192,7 @@ QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 1) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 1 parameter")); QVariant v = ctxt->argument(0).toVariant(); QColor color; if (v.userType() == QVariant::Color) @@ -1206,7 +1211,7 @@ QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEng QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 1) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 1 parameter")); QVariant v = ctxt->argument(0).toVariant(); QColor color; if (v.userType() == QVariant::Color) @@ -1300,7 +1305,7 @@ QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptE QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 2) - return engine->nullValue(); + return ctxt->throwError(QDeclarativeEngine::tr("expected 2 parameters")); //get color QVariant v = ctxt->argument(0).toVariant(); QColor color; diff --git a/src/declarative/qml/qdeclarativeerror.cpp b/src/declarative/qml/qdeclarativeerror.cpp index 7e8aac0..17e91e3 100644 --- a/src/declarative/qml/qdeclarativeerror.cpp +++ b/src/declarative/qml/qdeclarativeerror.cpp @@ -49,8 +49,27 @@ QT_BEGIN_NAMESPACE /*! \class QDeclarativeError - \since 4.7 - \brief The QDeclarativeError class encapsulates a QML error + \since 4.7 + \brief The QDeclarativeError class encapsulates a QML error. + + QDeclarativeError includes a textual description of the error, as well + as location information (the file, line, and column). The toString() + method creates a single-line, human-readable string containing all of + this information, for example: + \code + file:///home/user/test.qml:7:8: Invalid property assignment: double expected + \endcode + + You can use qDebug() or qWarning() to output errors to the console. This method + will attempt to open the file indicated by the error + and include additional contextual information. + \code + file:///home/user/test.qml:7:8: Invalid property assignment: double expected + y: "hello" + ^ + \endcode + + \sa QDeclarativeView::errors(), QDeclarativeComponent::errors() */ class QDeclarativeErrorPrivate { @@ -69,7 +88,7 @@ QDeclarativeErrorPrivate::QDeclarativeErrorPrivate() } /*! - Create an empty error object. + Creates an empty error object. */ QDeclarativeError::QDeclarativeError() : d(0) @@ -77,7 +96,7 @@ QDeclarativeError::QDeclarativeError() } /*! - Create a copy of \a other. + Creates a copy of \a other. */ QDeclarativeError::QDeclarativeError(const QDeclarativeError &other) : d(0) @@ -86,7 +105,7 @@ QDeclarativeError::QDeclarativeError(const QDeclarativeError &other) } /*! - Assign \a other to this error object. + Assigns \a other to this error object. */ QDeclarativeError &QDeclarativeError::operator=(const QDeclarativeError &other) { @@ -112,7 +131,7 @@ QDeclarativeError::~QDeclarativeError() } /*! - Return true if this error is valid, otherwise false. + Returns true if this error is valid, otherwise false. */ bool QDeclarativeError::isValid() const { @@ -120,7 +139,7 @@ bool QDeclarativeError::isValid() const } /*! - Return the url for the file that caused this error. + Returns the url for the file that caused this error. */ QUrl QDeclarativeError::url() const { @@ -129,7 +148,7 @@ QUrl QDeclarativeError::url() const } /*! - Set the \a url for the file that caused this error. + Sets the \a url for the file that caused this error. */ void QDeclarativeError::setUrl(const QUrl &url) { @@ -138,7 +157,7 @@ void QDeclarativeError::setUrl(const QUrl &url) } /*! - Return the error description. + Returns the error description. */ QString QDeclarativeError::description() const { @@ -147,7 +166,7 @@ QString QDeclarativeError::description() const } /*! - Set the error \a description. + Sets the error \a description. */ void QDeclarativeError::setDescription(const QString &description) { @@ -156,7 +175,7 @@ void QDeclarativeError::setDescription(const QString &description) } /*! - Return the error line number. + Returns the error line number. */ int QDeclarativeError::line() const { @@ -165,7 +184,7 @@ int QDeclarativeError::line() const } /*! - Set the error \a line number. + Sets the error \a line number. */ void QDeclarativeError::setLine(int line) { @@ -174,7 +193,7 @@ void QDeclarativeError::setLine(int line) } /*! - Return the error column number. + Returns the error column number. */ int QDeclarativeError::column() const { @@ -183,7 +202,7 @@ int QDeclarativeError::column() const } /*! - Set the error \a column number. + Sets the error \a column number. */ void QDeclarativeError::setColumn(int column) { @@ -192,7 +211,7 @@ void QDeclarativeError::setColumn(int column) } /*! - Return the error as a human readable string. + Returns the error as a human readable string. */ QString QDeclarativeError::toString() const { @@ -210,7 +229,7 @@ QString QDeclarativeError::toString() const \relates QDeclarativeError \fn QDebug operator<<(QDebug debug, const QDeclarativeError &error) - Output a human readable version of \a error to \a debug. + Outputs a human readable version of \a error to \a debug. */ QDebug operator<<(QDebug debug, const QDeclarativeError &error) diff --git a/src/declarative/qml/qdeclarativeextensionplugin.cpp b/src/declarative/qml/qdeclarativeextensionplugin.cpp index 762c642d..863bfc4 100644 --- a/src/declarative/qml/qdeclarativeextensionplugin.cpp +++ b/src/declarative/qml/qdeclarativeextensionplugin.cpp @@ -59,6 +59,11 @@ QT_BEGIN_NAMESPACE function, and exporting the class using the Q_EXPORT_PLUGIN2() macro. + QML extension plugins can be used to provide either application-specific or + library-like plugins. Library plugins should limit themselves to registering types, + as any manipulation of the engine's root context may cause conflicts + or other issues in the library user's code. + See \l {Extending QML in C++} for details how to write a QML extension plugin. See \l {How to Create Qt Plugins} for general Qt plugin documentation. @@ -85,7 +90,7 @@ QDeclarativeExtensionPlugin::QDeclarativeExtensionPlugin(QObject *parent) } /*! - Destructor. + Destroys the plugin. */ QDeclarativeExtensionPlugin::~QDeclarativeExtensionPlugin() { @@ -94,7 +99,9 @@ QDeclarativeExtensionPlugin::~QDeclarativeExtensionPlugin() /*! \fn void QDeclarativeExtensionPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri) - Initializes the extension from the \a uri using the \a engine. + Initializes the extension from the \a uri using the \a engine. Here an application + plugin might, for example, expose some data or objects to QML, + as context properties on the engine's root context. */ void QDeclarativeExtensionPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri) diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp index b992b9f..4be3472 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.cpp +++ b/src/declarative/qml/qdeclarativeimageprovider.cpp @@ -45,31 +45,39 @@ QT_BEGIN_NAMESPACE /*! \class QDeclarativeImageProvider - \brief The QDeclarativeImageProvider class provides an interface for threaded image requests. + \since 4.7 + \brief The QDeclarativeImageProvider class provides an interface for threaded image requests in QML. - Note: the request() method may be called by multiple threads, so ensure the + QDeclarativeImageProvider can be used by a QDeclarativeEngine to provide images to QML asynchronously. + The image request will be run in a low priority thread, allowing potentially costly image + loading to be done in the background, without affecting the performance of the UI. + + See the QDeclarativeEngine::addImageProvider() documentation for an + example of how a custom QDeclarativeImageProvider can be constructed and used. + + \note the request() method may be called by multiple threads, so ensure the implementation of this method is reentrant. \sa QDeclarativeEngine::addImageProvider() */ /*! - The destructor is virtual. + Destroys the image provider. */ QDeclarativeImageProvider::~QDeclarativeImageProvider() { } /*! - \fn QImage QDeclarativeImageProvider::request(const QString &id, QSize *size, const QSize& requested_size) + \fn QImage QDeclarativeImageProvider::request(const QString &id, QSize *size, const QSize& requestedSize) Implement this method to return the image with \a id. - If \a requested_size is a valid size, resize the image to that size before returning. + If \a requestedSize is a valid size, the image returned should be of that size. - In any case, \a size must be set to the (original) size of the image. + In all cases, \a size must be set to the original size of the image. - Note: this method may be called by multiple threads, so ensure the + \note this method may be called by multiple threads, so ensure the implementation of this method is reentrant. */ diff --git a/src/declarative/qml/qdeclarativeimageprovider.h b/src/declarative/qml/qdeclarativeimageprovider.h index 50b73fe..cc9c9af 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.h +++ b/src/declarative/qml/qdeclarativeimageprovider.h @@ -54,7 +54,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeImageProvider { public: virtual ~QDeclarativeImageProvider(); - virtual QImage request(const QString &id, QSize *size, const QSize& requested_size) = 0; + virtual QImage request(const QString &id, QSize *size, const QSize& requestedSize) = 0; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativelist.cpp b/src/declarative/qml/qdeclarativelist.cpp index 45b8cd7..31ef4c2 100644 --- a/src/declarative/qml/qdeclarativelist.cpp +++ b/src/declarative/qml/qdeclarativelist.cpp @@ -87,9 +87,10 @@ void QDeclarativeListReferencePrivate::release() /*! \class QDeclarativeListReference +\since 4.7 \brief The QDeclarativeListReference class allows the manipulation of QDeclarativeListProperty properties. -QDeclarativeListReference allows programs to read from, and assign values to a QML list property in a +QDeclarativeListReference allows C++ programs to read from, and assign values to a QML list property in a simple and type safe way. A QDeclarativeListReference can be created by passing an object and property name or through a QDeclarativeProperty instance. These two are equivalant: @@ -304,6 +305,7 @@ int QDeclarativeListReference::count() const /*! \class QDeclarativeListProperty +\since 4.7 \brief The QDeclarativeListProperty class allows applications to explose list-like properties to QML. @@ -313,10 +315,10 @@ The use of a list property from QML looks like this: \code FruitBasket { fruit: [ - Apple {}, - Orange{}, - Banana {} - ] + Apple {}, + Orange{}, + Banana{} + ] } \endcode @@ -336,6 +338,9 @@ Q_PROPERTY(QDeclarativeListProperty<Fruit> fruit READ fruit); QML list properties are typesafe - in this case \c {Fruit} is a QObject type that \c {Apple}, \c {Orange} and \c {Banana} all derive from. + +\note QDeclarativeListProperty can only be used for lists of QObject-derived object pointers. + */ /*! diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index afd0d84..3881d0a 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE /*! \class QDeclarativeProperty +\since 4.7 \brief The QDeclarativeProperty class abstracts accessing properties on objects created from QML. As QML uses Qt's meta-type system all of the existing QMetaObject classes can be used to introspect |