📄 qmetatype.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtCore module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qmetatype.h"#include "qobjectdefs.h"#include "qbytearray.h"#include "qreadwritelock.h"#include "qstring.h"#include "qvector.h"/*! \macro Q_DECLARE_METATYPE(Type) \relates QMetaType This macro makes the type \a Type known to QMetaType. It is needed to use the type \a Type as a custom type in QVariant. Ideally, this macro should be placed below the declaration of the class or struct. If that is not possible, it can be put in a private header file which has to be included every time that type is used in a QVariant. Q_DECLARE_METATYPE() doesn't actually register the type; you must still use qRegisterMetaType() for that, particularly if you intend to use the type in signal and slot connections. This example shows a typical use case of Q_DECLARE_METATYPE(): \code struct MyStruct { int i; ... }; Q_DECLARE_METATYPE(MyStruct) \endcode If \c MyStruct is in a namespace, the Q_DECLARE_METATYPE() macro has to be outside the namespace: \code namespace MyNamespace { ... } Q_DECLARE_METATYPE(MyNamespace::MyStruct) \endcode Since \c{MyStruct} is now known to QMetaType, it can be used in QVariant: \code MyStruct s; QVariant var; var.setValue(s); // copy s into the variant ... // retrieve the value MyStruct s2 = var.value<MyStruct>(); \endcode \sa qRegisterMetaType()*//*! \enum QMetaType::Type These are the built-in types supported by QMetaType: \value Void \c void \value Bool \c bool \value Int \c int \value UInt \c{unsigned int} \value Double \c double \value QChar QChar \value QString QString \value QByteArray QByteArray \value VoidStar \c{void *} \value Long \c{long} \value Short \c{short} \value Char \c{char} \value ULong \c{unsigned long} \value UShort \c{unsigned short} \value UChar \c{unsigned char} \value Float \c float \value QObjectStar QObject * \value QWidgetStar QWidget * \value User Base value for user types Additional types can be registered using qRegisterMetaType(). \sa type(), typeName()*//*! \class QMetaType \brief The QMetaType class manages named types in the meta-object system. \ingroup objectmodel \threadsafe The class is used as a helper to marshall types in QVariant and in queued signals and slots connections. It associates a type name to a type so that it can be created and destructed dynamically at run-time. Register new types with qRegisterMetaType(). Any class or struct that has a public default constructor, a public copy constructor, and a public destructor can be registered. The following code allocates and destructs an instance of \c{MyClass}: \code int id = QMetaType::type("MyClass"); if (id != -1) { void *myClassPtr = QMetaType::construct(id); ... QMetaType::destroy(id, myClassPtr); myClassPtr = 0; } \endcode The Q_DECLARE_METATYPE() macro can be used to register a type at compile time. This is required to use the type as custom type in QVariant. If we want the stream operators \c operator<<() and \c operator>>() to work on QVariant objects that store custom types, the custom type must provide \c operator<<() and \c operator>>() operators and register them using qRegisterMetaTypeStreamOperators(). \sa Q_DECLARE_METATYPE(), QVariant::setValue(), QVariant::value(), QVariant::fromValue()*/static const struct { const char * typeName; int type; } types[] = { {"void*", QMetaType::VoidStar}, {"long", QMetaType::Long}, {"int", QMetaType::Int}, {"short", QMetaType::Short}, {"char", QMetaType::Char}, {"ulong", QMetaType::ULong}, {"unsigned long", QMetaType::ULong}, {"uint", QMetaType::UInt}, {"unsigned int", QMetaType::UInt}, {"ushort", QMetaType::UShort}, {"unsigned short", QMetaType::UShort}, {"uchar", QMetaType::UChar}, {"unsigned char", QMetaType::UChar}, {"bool", QMetaType::Bool}, {"float", QMetaType::Float}, {"double", QMetaType::Double}, {"QChar", QMetaType::QChar}, {"QByteArray", QMetaType::QByteArray}, {"QString", QMetaType::QString}, {"QObject*", QMetaType::QObjectStar}, {"QWidget*", QMetaType::QWidgetStar}, {"void", QMetaType::Void}, {"", QMetaType::Void}, {0, QMetaType::Void}};class QCustomTypeInfo{public: QCustomTypeInfo() : typeName(0, '\0'), constr(0), destr(0)#ifndef QT_NO_DATASTREAM , saveOp(0), loadOp(0)#endif {} inline void setData(const char *tname, QMetaType::Constructor cp, QMetaType::Destructor de) { typeName = tname; constr = cp; destr = de; } inline void setData(QMetaType::Constructor cp, QMetaType::Destructor de) { constr = cp; destr = de; }#ifndef QT_NO_DATASTREAM inline void setOperators(QMetaType::SaveOperator sOp, QMetaType::LoadOperator lOp) { saveOp = sOp; loadOp = lOp; }#endif QByteArray typeName; QMetaType::Constructor constr; QMetaType::Destructor destr;#ifndef QT_NO_DATASTREAM QMetaType::SaveOperator saveOp; QMetaType::LoadOperator loadOp;#endif};Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)#ifndef QT_NO_DATASTREAM/*! \internal*/void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp, LoadOperator loadOp){ int idx = type(typeName); if (!idx) return; QVector<QCustomTypeInfo> *ct = customTypes(); if (!ct) return; QWriteLocker locker(customTypesLock()); (*ct)[idx - User].setOperators(saveOp, loadOp);}#endif/*! Returns the type name associated with the given \a type, or 0 if no matching type was found. The returned pointer must not be deleted. \sa type(), isRegistered(), Type*/const char *QMetaType::typeName(int type){ if (type >= User) { if (!isRegistered(type)) return 0; const QVector<QCustomTypeInfo> * const ct = customTypes(); if (!ct) return 0; QReadLocker locker(customTypesLock()); return ct->at(type - User).typeName.constData(); } int i = 0; while (types[i].typeName) { if (types[i].type == type) return types[i].typeName; ++i; } return 0;}/*! \internal Same as QMetaType::type(), but doesn't lock.*/static int qMetaTypeType_unlocked(const char *typeName){ if (!typeName) return 0; int i = 0; while (types[i].typeName && strcmp(typeName, types[i].typeName)) ++i; if (!types[i].type) { const QVector<QCustomTypeInfo> * const ct = customTypes(); if (!ct) return 0; for (int v = 0; v < ct->count(); ++v) { if (strcmp(ct->at(v).typeName, typeName) == 0) return v + QMetaType::User; } } return types[i].type;}/*! \internal Registers a user type for marshalling, with \a typeName, a \a destructor, and a \a constructor. Returns the type's handle, or -1 if the type could not be registered. */int QMetaType::registerType(const char *typeName, Destructor destructor, Constructor constructor){ QVector<QCustomTypeInfo> *ct = customTypes(); if (!ct || !typeName || !destructor || !constructor) return -1; QWriteLocker locker(customTypesLock()); static int currentIdx = User; int idx = qMetaTypeType_unlocked(typeName); if (idx) { if (idx < User) { qWarning("cannot re-register basic type '%s'", typeName); return -1; } (*ct)[idx - User].setData(constructor, destructor); } else { idx = currentIdx++; ct->resize(ct->count() + 1); (*ct)[idx - User].setData(typeName, constructor, destructor); } return idx;}/*! Returns true if the custom datatype with ID \a type is registered; otherwise returns false. \sa type(), typeName(), Type*/bool QMetaType::isRegistered(int type){ QReadLocker locker(customTypesLock()); const QVector<QCustomTypeInfo> * const ct = customTypes(); return (type >= User) && (ct && ct->count() > type - User);}/*! Returns a handle to the type called \a typeName, or 0 if there is no such type. \sa isRegistered(), typeName(), Type*/int QMetaType::type(const char *typeName)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -