1
votes

I have following C++ custom object, which is wished to be used in QML as enum type:

#include <QtQml>
#include <QApplication>
#include <QQmlApplicationEngine>

#include "database/uepeoplemodel.h"
#include "core/uestatus.h"
#include "core/uedatabaseconnectionstatus.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;

    UeStatus* ueApplicationStatus=new UeStatus(qApp);
    UePeopleModel* uePeopleModel=new UePeopleModel(qApp);

    QObject::connect(uePeopleModel,
                     SIGNAL(ueSignalDatabaseConnectionChanged(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus)),
                     ueApplicationStatus,
                     SLOT(ueSignalDatabaseConnectionChanged(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus)));

    uePeopleModel->ueConnectToDatabase();

    engine.rootContext()->setContextProperty("uePeopleModel",
                                             uePeopleModel);
    engine.rootContext()->setContextProperty("ueApplicationStatus",
                                             ueApplicationStatus);
    engine.addImageProvider(QLatin1String("uePeopleModel"),
                            uePeopleModel);

    qmlRegisterUncreatableType<UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus>("si.mikroelektronika",
                                                                                           1,
                                                                                           0,
                                                                                           "UeTypeDatabaseConnectionStatus",
                                                                                           "Database Connection Status");

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

I get following compile errors (using gcc version 4.9.2 on Linux work002 3.19.0-28-generic #30-Ubuntu SMP Mon Aug 31 15:52:51 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux:

In file included from /opt/QtOpenSource55/5.5/gcc_64/include/QtCore/qobject.h:40:0, from /opt/QtOpenSource55/5.5/gcc_64/include/QtCore/qabstractanimation.h:37, from /opt/QtOpenSource55/5.5/gcc_64/include/QtCore/QtCore:4, from /opt/QtOpenSource55/5.5/gcc_64/include/QtQml/QtQmlDepends:3, from /opt/QtOpenSource55/5.5/gcc_64/include/QtQml/QtQml:3, from ../ueBlagajnaClient/main.cpp:1: /opt/QtOpenSource55/5.5/gcc_64/include/QtCore/qobjectdefs.h:88:5: error: class definition may not be declared a friend friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) Q_DECL_NOEXCEPT { return &staticMetaObject; } \ ^ ../ueBlagajnaClient/database/../core/uedatabaseconnectionstatus.h:17:5: note: in expansion of macro 'Q_ENUM' Q_ENUM(UeTypeDatabaseConnectionStatus) ^ /opt/QtOpenSource55/5.5/gcc_64/include/QtCore/qobjectdefs.h:88:35: error: 'QMetaObject' is neither function nor member function; cannot be declared friend friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) Q_DECL_NOEXCEPT { return &staticMetaObject; } \ ^ ../ueBlagajnaClient/database/../core/uedatabaseconnectionstatus.h:17:5: note: in expansion of macro 'Q_ENUM' Q_ENUM(UeTypeDatabaseConnectionStatus) ^ /opt/QtOpenSource55/5.5/gcc_64/include/QtCore/qobjectdefs.h:88:35: error: expected ';' at end of member declaration friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) Q_DECL_NOEXCEPT { return &staticMetaObject; } \ ^ ../ueBlagajnaClient/database/../core/uedatabaseconnectionstatus.h:17:5: note: in expansion of macro 'Q_ENUM' Q_ENUM(UeTypeDatabaseConnectionStatus) ^ /opt/QtOpenSource55/5.5/gcc_64/include/QtCore/qobjectdefs.h:88:73: error: ISO C++ forbids declaration of 'qt_getEnumMetaObject' with no type [-fpermissive] friend Q_DECL_CONSTEXPR const QMetaObject qt_getEnumMetaObject(ENUM) Q_DECL_NOEXCEPT { return &staticMetaObject; } \ ^ ../ueBlagajnaClient/database/../core/uedatabaseconnectionstatus.h:17:5: note: in expansion of macro 'Q_ENUM' Q_ENUM(UeTypeDatabaseConnectionStatus) ^ ../ueBlagajnaClient/database/../core/uedatabaseconnectionstatus.h: In member function 'int UeDatabaseConnectionStatus::qt_getEnumMetaObject(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus)': /opt/QtOpenSource55/5.5/gcc_64/include/QtCore/qobjectdefs.h:88:101: error: cannot convert 'const QMetaObject*' to 'int*' in return friend Q_DECL_CONSTEXPR const QMetaObject qt_getEnumMetaObject(ENUM) Q_DECL_NOEXCEPT { return &staticMetaObject; } \ ^ ../ueBlagajnaClient/database/../core/uedatabaseconnectionstatus.h:17:5: note: in expansion of macro 'Q_ENUM' Q_ENUM(UeTypeDatabaseConnectionStatus) ^ In file included from /opt/QtOpenSource55/5.5/gcc_64/include/QtQml/QtQml:9:0, from ../ueBlagajnaClient/main.cpp:1: /opt/QtOpenSource55/5.5/gcc_64/include/QtQml/qqml.h: In instantiation of 'int qmlRegisterUncreatableType(const char, int, int, const char*, const QString&) [with T = UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus]': ../ueBlagajnaClient/main.cpp:35:120: required from here /opt/QtOpenSource55/5.5/gcc_64/include/QtQml/qqml.h:83:59: error: 'staticMetaObject' is not a member of 'UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus' const char *className = T::staticMetaObject.className(); \ ^ /opt/QtOpenSource55/5.5/gcc_64/include/QtQml/qqml.h:134:5: note: in expansion of macro 'QML_GETTYPENAMES' QML_GETTYPENAMES ^ In file included from /opt/QtOpenSource55/5.5/gcc_64/include/QtQml/QtQml:9:0, from ../ueBlagajnaClient/main.cpp:1: /opt/QtOpenSource55/5.5/gcc_64/include/QtQml/qqml.h:144:51: error: 'staticMetaObject' is not a member of 'UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus' uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, ^ Makefile:1319: recipe for target 'main.o' failed make: *** [main.o] Error 1 08:04:15: The process "/usr/bin/make" exited with code 2. Error while building/deploying project ueBlagajnaClient (kit: Desktop Qt 5.5.0 GCC 64bit) When executing step "Make"

Why and how do I get rid of this error? How am I misusing method qmlRegisterUncreatableType?

1
Is declaration of UeTypeDatabaseConnectionStatus visible for the place where you call qmlRegisterType ?Max Go
@N1ghtLight yes it is, the header file is included in main.cppKernelPanic

1 Answers

4
votes

If you want to use qmlRegisterType, the class used must be a class that inherits QObject and has the Q_OBJECT macro:

class UeTypeDatabaseConnectionStatus: public QObject
{
    Q_OBJECT

public:
    enum StatusEnum
    {
        NOT_CONNECTED=false,
        CONNECTED=true
    }
    Q_ENUM(StatusEnum)
    ...
}

In QML, you can create an instance of it, just like you do with any other QML-class.

EDIT: However, since all you want to do is use the enum-values, use qmlRegisterUncreatableType instead. This way the type gets registered, but you can't create an instance of it.

To access the enum values, import the type and use it like any other enum:

connectionProperty: UeTypeDatabaseConnectionStatus.CONNECTED;