Qmetatype::user weirdness



  • I'd like to iterate over all registered user types, so I do this:

    @
    for(int i = QMetaType::User; i < 1000 && !done; i++)
    {
    qDebug() << i << ": " << QMetaType::typeName(i);

      if(QMetaType::isRegistered(i))
      {
         QObject* pObj = (QObject*)QMetaType::construct(i);
    
         if(pObj->inherits("AcmeCommand"))
         {
            if(((AcmeCommand*)pObj)->commandGroup == commandGroup)
            {
               list.append((AcmeCommand*)pObj);
            }
         }
      }
      else { done = true; }
    

    }
    @

    The problem is that my code crashes and it is because there are some weird types in which seem to have been registered in the user section:

    256 : QPaintBufferCacheEntry
    257 : QPaintBufferCacheEntryV2

    I get those printed out by removing the casts in the above code (which causes a seg fault because the two types don't inherit from QObject, so it barfs).

    So what the crap is up with these two types being in my personal private types section?

    Qt 4.8.4, Ubuntu 12.10. 32-bit.

    M


  • Lifetime Qt Champion

    Hi,

    Did you verify the return value of qRegisterMetaType for your custom types ?



  • The metaTypeIds consist of built-in types and user types.

    All the built-in types has been list in QTetaType's manual page.

    Types declared with Q_DECLARE_METATYPE is called user types.
    The values of the types id depends on the order of the qRegisterMetaType() called.

    @
    corelib/tools/qlocale_p.h:Q_DECLARE_METATYPE(QStringRef)
    corelib/tools/qlocale_p.h:Q_DECLARE_METATYPE(QListQt::DayOfWeek)
    corelib/tools/qlocale_p.h:Q_DECLARE_METATYPE(QSystemLocale::CurrencyToStringArgu
    dbus/doc/snippets/code/src_qdbus_qdbusargument.cpp:Q_DECLARE_METATYPE(MyStructur
    dbus/doc/src/dbus-adaptors.qdoc: declared as a Qt meta-type with the Q_DECLAR
    dbus/qdbusargument.h:Q_DECLARE_METATYPE(QDBusArgument)
    dbus/qdbuserror.h:Q_DECLARE_METATYPE(QDBusError)
    dbus/qdbusextratypes.h:Q_DECLARE_METATYPE(QDBusVariant)
    dbus/qdbusextratypes.h:Q_DECLARE_METATYPE(QDBusObjectPath)
    dbus/qdbusextratypes.h:Q_DECLARE_METATYPE(QDBusSignature)
    dbus/qdbusintegrator_p.h:Q_DECLARE_METATYPE(QDBusSlotCache)
    dbus/qdbusmessage.h:Q_DECLARE_METATYPE(QDBusMessage)
    dbus/qdbusmetatype.cpp: Q_DECLARE_METATYPE() macro, and then registered as in
    dbus/qdbusunixfiledescriptor.h:Q_DECLARE_METATYPE(QDBusUnixFileDescriptor)
    gui/math3d/qgenericmatrix.h:Q_DECLARE_METATYPE(QMatrix2x2)
    gui/math3d/qgenericmatrix.h:Q_DECLARE_METATYPE(QMatrix2x3)
    gui/math3d/qgenericmatrix.h:Q_DECLARE_METATYPE(QMatrix2x4)
    gui/math3d/qgenericmatrix.h:Q_DECLARE_METATYPE(QMatrix3x2)
    gui/math3d/qgenericmatrix.h:Q_DECLARE_METATYPE(QMatrix3x3)
    gui/math3d/qgenericmatrix.h:Q_DECLARE_METATYPE(QMatrix3x4)
    gui/math3d/qgenericmatrix.h:Q_DECLARE_METATYPE(QMatrix4x2)
    gui/math3d/qgenericmatrix.h:Q_DECLARE_METATYPE(QMatrix4x3)
    gui/opengl/qopengldebug.h:Q_DECLARE_METATYPE(QOpenGLDebugMessage)
    gui/painting/qpaintbuffer.cpp:Q_DECLARE_METATYPE(QPaintBufferCacheEntry)
    gui/painting/qpaintbuffer.cpp:Q_DECLARE_METATYPE(QPaintBufferCacheEntryV2)
    gui/text/qcssparser_p.h:Q_DECLARE_METATYPE( QCss::BackgroundData )
    gui/text/qcssparser_p.h:Q_DECLARE_METATYPE( QCss::LengthData )
    gui/text/qcssparser_p.h:Q_DECLARE_METATYPE( QCss::BorderData )
    gui/text/qstatictext.h:Q_DECLARE_METATYPE(QStaticText)
    gui/text/qtextoption.h:Q_DECLARE_METATYPE( QTextOption::Tab )
    network/access/qhttpnetworkrequest_p.h:Q_DECLARE_METATYPE(QHttpNetworkRequest)
    network/access/qnetworkaccesscache_p.h:Q_DECLARE_METATYPE(QNetworkAccessCache::C
    network/access/qnetworkcookie.h:Q_DECLARE_METATYPE(QNetworkCookie)
    network/access/qnetworkreply.h:Q_DECLARE_METATYPE(QNetworkReply::NetworkError)
    network/access/qnetworkreplyimpl_p.h:Q_DECLARE_METATYPE(QSharedPointer<char>)
    network/access/qnetworkrequest.h:Q_DECLARE_METATYPE(QNetworkRequest)
    network/bearer/qnetworkconfiguration.h:Q_DECLARE_METATYPE(QNetworkConfiguration)
    network/bearer/qnetworkconfiguration_p.h:Q_DECLARE_METATYPE(QNetworkConfiguratio
    network/bearer/qnetworksession.h:Q_DECLARE_METATYPE(QNetworkSession::State)
    network/bearer/qnetworksession.h:Q_DECLARE_METATYPE(QNetworkSession::SessionErro
    network/bearer/qnetworksession.h:Q_DECLARE_METATYPE(QNetworkSession::UsagePolici
    network/kernel/qdnslookup_p.h:Q_DECLARE_METATYPE(QDnsLookupReply)
    network/kernel/qhostinfo.h:Q_DECLARE_METATYPE(QHostInfo)
    network/kernel/qnetworkproxy.h:Q_DECLARE_METATYPE(QNetworkProxy)
    network/socket/qabstractsocket.h:Q_DECLARE_METATYPE(QAbstractSocket::SocketState
    network/socket/qabstractsocket.h:Q_DECLARE_METATYPE(QAbstractSocket::SocketError
    network/ssl/qsslcertificate.h:Q_DECLARE_METATYPE(QSslCertificate)
    network/ssl/qsslconfiguration.h:Q_DECLARE_METATYPE(QSslConfiguration)
    network/ssl/qsslerror.h:Q_DECLARE_METATYPE(QList<QSslError>)
    opengl/qgl_p.h:Q_DECLARE_METATYPE(GLuint)
    printsupport/kernel/qprintengine_win.cpp:Q_DECLARE_METATYPE(HFONT)
    printsupport/kernel/qprintengine_win.cpp:Q_DECLARE_METATYPE(LOGFONT)
    sql/drivers/mysql/qsql_mysql.cpp:Q_DECLARE_METATYPE(MYSQL_RES*)
    sql/drivers/mysql/qsql_mysql.cpp:Q_DECLARE_METATYPE(MYSQL*)
    sql/drivers/mysql/qsql_mysql.cpp:Q_DECLARE_METATYPE(MYSQL_STMT*)
    sql/drivers/oci/qsql_oci.cpp:Q_DECLARE_METATYPE(OCIEnv*)
    sql/drivers/oci/qsql_oci.cpp:Q_DECLARE_METATYPE(OCIStmt*)
    sql/drivers/oci/qsql_oci.cpp:Q_DECLARE_METATYPE(QOCIRowIdPointer)
    sql/drivers/psql/qsql_psql.cpp:Q_DECLARE_METATYPE(PGconn*)
    sql/drivers/psql/qsql_psql.cpp:Q_DECLARE_METATYPE(PGresult*)
    sql/drivers/sqlite/qsql_sqlite.cpp:Q_DECLARE_METATYPE(sqlite3*)
    sql/drivers/sqlite/qsql_sqlite.cpp:Q_DECLARE_METATYPE(sqlite3_stmt*)
    sql/drivers/sqlite2/qsql_sqlite2.cpp:Q_DECLARE_METATYPE(sqlite_vm*)
    sql/drivers/sqlite2/qsql_sqlite2.cpp:Q_DECLARE_METATYPE(sqlite*)
    widgets/dialogs/qwizard_win.cpp:Q_DECLARE_METATYPE(QMargins)
    widgets/graphicsview/qgraphicsitem.h:Q_DECLARE_METATYPE(QGraphicsItem )
    widgets/kernel/qgesture.h:Q_DECLARE_METATYPE(Qt::GestureState)
    widgets/kernel/qgesture.h:Q_DECLARE_METATYPE(Qt::GestureType)
    widgets/kernel/qgesture.h:Q_DECLARE_METATYPE(QPinchGesture::ChangeFlags)
    widgets/kernel/qgesture.h:Q_DECLARE_METATYPE(QGesture::GestureCancelPolicy)
    widgets/styles/qgtkstyle_p.cpp:Q_DECLARE_METATYPE(QGtkStylePrivate
    );
    widgets/util/qscrollerproperties.h:Q_DECLARE_METATYPE(QScrollerProperties::Overs
    widgets/util/qscrollerproperties.h:Q_DECLARE_METATYPE(QScrollerProperties::Frame
    ...
    @



  • Yeah, I understand how it works... I guess what I'm saying is that I expected types starting at UserType and after to be, well, user types.

    I'm curious where these two types come from because I most certainly did not add them.

    And if I modify the loop to only print out user types (up to 1000), I get all the rest of the types I've put in. It is important to me because every type I register is a QObject sublcass but these other ones apparently are not.



  • [quote author="SGaist" date="1372191002"]Hi,

    Did you verify the return value of qRegisterMetaType for your custom types ?[/quote]

    No, but they all are printed after those two above, so it seems like they are getting registered correctly. It is just that someone else is putting those two types in my user types section!



  • [quote author="medvedm" date="1372250785"]Yeah, I understand how it works... I guess what I'm saying is that I expected types starting at UserType and after to be, well, user types.
    [/quote]

    No, you still don't understand it. ;-)

    MetaType is is used by Qt widely, but only a small of them is built-in. user metaType is used wide by Qt itself too. I have list some of them in last post.

    In other world, the user metatype doesn't mean types of USER explicit defined class or types.

    [quote author="medvedm" date="1372250785"]
    I'm curious where these two types come from because I most certainly did not add them.
    [/quote]
    As they are registered by the Qt code you called though you didn't notice.

    You can try to play with code like following

    @
    #include <QtCore>
    #include <QtNetwork>
    class MyClass
    {};
    Q_DECLARE_METATYPE(MyClass)

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    QHostInfo::lookupHost("qt-project.org", &a, SLOT(not_exists_slot(QHostInfo)));
    qRegisterMetaType<MyClass>();
    
    qDebug()<<qMetaTypeId<QHostInfo>();
    qDebug()<<qMetaTypeId<MyClass>();
    
    return 0;
    

    }
    @
    QHostInfo will get register when you called QHostInfo::lookupHost. If you move this line below the qRegisterMetaType, you will get different result. And of cause, you can delete one of them, then they will be registered by the call to qMetaTypeId.



  • Er...

    As you using Qt4 instead of Qt5, you should play with following example instead of last one(that can not compiled under Qt4).

    @
    #include <QtCore>
    #include <QtNetwork>

    class MyClass
    {

    };
    Q_DECLARE_METATYPE(MyClass)

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    QHostInfo::lookupHost("qt-project.org", &a, SLOT(not_exists_slot(QHostInfo)));
    qRegisterMetaType<MyClass>();
    
    qDebug()<<QMetaType::type("QHostInfo");
    qDebug()<<QMetaType::type("MyClass");
    
    return 0;
    

    }
    @



  • [quote author="medvedm" date="1372250887"]
    It is just that someone else is putting those two types in my user types section![/quote]

    No, it's not your user types section, it's the types scetion above the built-in types, and it can be registered and used both by User and Qt itself.



  • Ok, it seems to me it is unfortunate that they use the word USER repeatedly if the section is used by types other than USER types. There should be a section (say 255-700 or something) of types that Qt uses if it registers types at run time and a section (above 1000 or something?) that are truly for the USERS's use (and no one else). LIke maybe there should be a Q_DECLARE_USER_METATYPE and Q_DELCARE_QT_METATYPE.

    The problem is this - I want to iterate over all types that I have registered and do some things. These things require the type to be a QObject, which is not a requirement for a type registered into the QMetaType list. AFAIK there is no way for me to figure out if a class is a QObject without using ->inherits(), which is only available for QObject sublcasses.

    So, If I could know that the types which I register start and end in a certain range, I could know that they were QObject subclasses. Am I just SOL?

    M


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.