Understanding QML, C++, and Enumerations
-
I have a test project at state_binding_test
In main.cpp, I have:
int main(int argc, char *argv[]) { QCoreApplication::setAttribute( Qt::AA_EnableHighDpiScaling ); QGuiApplication app( argc, argv ); qmlRegisterSingletonType<StateMachine>( "com.company.statemachine", 1, 0, "StateMachine", &StateMachine::qmlSingletonInstance ); qmlRegisterUncreatableType<Support>( "com.company.statemachine.support", 1, 0, "Support", QStringLiteral( "Support should not be created in QML" ) ); qRegisterMetaType<Support::ETestB>( "Support.ETestB" ); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
In support.h, I have
enum class ETestB { Ddddd, Eeeee, Fffff }; Q_ENUM( ETestB );
In main.qml, I have:
Label { id: label x: 54 width: 502 height: 33 text: { console.log( "Aaaaa: ", StateMachine.Aaaaa ); console.log( "Aaaaa: ", StateMachine.Bbbbb ); console.log( "Aaaaa: ", StateMachine.Ccccc ); console.log( "Ddddd: ", Support.Ddddd ); console.log( "Eeeee: ", Support.Eeeee ); console.log( "Fffff: ", Support.Fffff ); return StateMachine.support.title; } anchors.top: parent.top font.bold: true font.pointSize: 24 anchors.topMargin: 49 anchors.horizontalCenter: parent.horizontalCenter }
When I run the app, I see in the output:
qml: Ddddd: 0 qml: Eeeee: 1 qml: Fffff: 2
which is what is expected. However, I still have a few questions:
-
Does or should
qmlRegisterUncreatableType
andqRegisterMetaType
need to go in main.cpp and be executed afterQGuiApplication app
? Or is considered best practice, etc.? -
console.log( "Ddddd: ", Support.Ddddd );
works, but I lose the explicit connection to the ETestB datatype. I would prefer to be able to write Support.ETestB.Ddddd or something. Is that possible now or something that might be implemented in a future version? -
If I remove
qRegisterMetaType
, current behavior remains the same. I am not sure what, exactly, qRegisterMetaType is doing for me here. Can someone provide some insight...? -
Let's say that I add:
enum class ETestC { Ggggg, Ddddd, Eeeee, Fffff }; Q_ENUM( ETestC );
to the Support class. And
qRegisterMetaType<Support::ETestC>( "Support.ETestC" );
to the main function. There is now a namespace collision between ETestC and ETestB. According to some documentation, it seems like I should addQ_CLASSINFO( "RegisterEnumClassesUnscoped", "false" )
to the Support class. However, when I do all of that, I see:qml: Ddddd: undefined qml: Eeeee: undefined qml: Fffff: undefined
in the output. Clearly there is something I did not understand from the documentation.
I look forward to hearing from anyone who cares to comment so I can understand this system better.
-
-
@james_h_3010 said in Understanding QML, C++, and Enumerations:
- Does or should
qmlRegisterUncreatableType
andqRegisterMetaType
need to go in main.cpp and be executed afterQGuiApplication app
? Or is considered best practice, etc.?
It does not need to be in main.cpp. It does need to be executed after QGuiApplication.
What you wrote is how most people do it. Is it best practice? Well, for big projects I'd say it's good to move that stuff to some other header, just to keep main.cpp cleaner. But it does not matter much, it's only styling "issue". You won't gain or loose performance here.
console.log( "Ddddd: ", Support.Ddddd );
works, but I lose the explicit connection to the ETestB datatype. I would prefer to be able to write Support.ETestB.Ddddd or something. Is that possible now or something that might be implemented in a future version?
I don't think it's supported and I have not heard of plans to support it. Maybe it will come, though, who knows.
- If I remove
qRegisterMetaType
, current behavior remains the same. I am not sure what, exactly, qRegisterMetaType is doing for me here. Can someone provide some insight...?
Q_ENUM has already registered it with meta object system. You don't need to do it manually.
- Let's say that I add:
enum class ETestC { Ggggg, Ddddd, Eeeee, Fffff }; Q_ENUM( ETestC );
to the Support class. And
qRegisterMetaType<Support::ETestC>( "Support.ETestC" );
to the main function. There is now a namespace collision between ETestC and ETestB. According to some documentation, it seems like I should addQ_CLASSINFO( "RegisterEnumClassesUnscoped", "false" )
to the Support class. However, when I do all of that, I see:qml: Ddddd: undefined qml: Eeeee: undefined qml: Fffff: undefined
in the output. Clearly there is something I did not understand from the documentation.
I look forward to hearing from anyone who cares to comment so I can understand this system better.
I think they would clash, yes. QML engine is very stupid when it comes to understanding enums.
- Does or should