Help structuring code with QML modules
-
Hello,
Trying my hand at using QML modules (in the way of recent Qt versions) and thought I'd write a basic QML app using a singleton Style module, but I'm running into issues, probably due to import paths?
If anyone can enlighten me about what is wrong here, it'd be greatly appreciated! Maybe my project structure is just plain wrong and of course it could be simpler, but this is a test bed for more complicated programs with several modules that I want to make, so the question is is this a good base for more complex apps?Here goes:
MyProject/ ├── CMakeLists.txt ├── src/ │ ├── CMakeLists.txt │ ├── StyleModule/ │ │ ├── CMakeLists.txt │ │ ├── MyStyle.qml │ ├── MainApp/ │ │ ├── CMakeLists.txt │ │ ├── Main.qml │ │ └── main.cpp
MyProject/CMakeLists.txt:
cmake_minimum_required(VERSION 3.21) project(QmlStyleSingleton LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 17) find_package(Qt6 6.8 REQUIRED COMPONENTS Quick) qt_standard_project_setup( REQUIRES 6.8 ) add_subdirectory(src)
MyProject/src/CMakeLists.txt:
add_subdirectory(StyleModule) add_subdirectory(MainApp)
MyProject/src/MainApp/CMakeLists.txt:
qt_add_executable(MainApp main.cpp ) qt_add_qml_module(MainApp URI MainModule VERSION 1.0 QML_FILES Main.qml ) target_link_libraries(MainApp PRIVATE Qt6::Quick StyleModule # StyleModuleplugin > tried like this as well )
MyProject/src/MainApp/main.cpp:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlExtensionPlugin> int main( int argc, char * argv[] ) { QGuiApplication app( argc, argv ); QQmlApplicationEngine engine; QObject::connect( &engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QCoreApplication::exit( -1 ); }, Qt::QueuedConnection ); // Q_IMPORT_QML_PLUGIN( StyleModulePlugin ); // Needed? engine.loadFromModule( "MainModule", "Main" ); return app.exec(); }
MyProject/src/MainApp/Main.qml:
import QtQuick import QtQuick.Controls import StyleModule ApplicationWindow { visible: true width: 400 height: 300 title: "Window Title" Rectangle { anchors.fill: parent color: MyStyle.mycolor Text { text: "Hello" color: MyStyle.myothercolor anchors.centerIn: parent } } }
MyProject/src/StyleModule/CMakeLists.txt:
# qt_add_library(StyleModule STATIC) # > tried as well qt_add_qml_module(StyleModule URI StyleModule VERSION 1.0 QML_FILES MyStyle.qml ) target_link_libraries(StyleModule PRIVATE Qt6::Quick)
MyProject/src/StyleModule/MyStyle.qml:
pragma Singleton import QtQuick QtObject { property color mycolor: "#111222" property color myothercolor: "lightgray" }
Basically, the program runs, but MyStyle is not found at runtime and I get these errors:
qrc:/qt/qml/MainModule/Main.qml:13:9: Unable to assign [undefined] to QColor
Also in Qt Creator I get a warning about the StyleModule import:
warning: Failed to import StyleModule. Are your import paths set up properly? [import]
Any help, or general guideline appreciated!
Thanks, -
MyStyle is not registered.
https://doc.qt.io/qt-6/qml-singleton.html -
Thank you for looking into this, and pointing me to the doc...
What actually made it work at runtime was adding this to the Style module CMakeLists (before qt_add_qml_module):
set_source_files_properties( MySingleton.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE )
However, in Qt Creator, I still get an error in my Main.qml file, saying QML module not found (StyleModule). And code completion does not work on the MyStyle object.
I fixed it by adding these two commands to the root CMakeLists:
set( QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/qml ) set( QML_IMPORT_PATH ${QT_QML_OUTPUT_DIRECTORY} CACHE PATH "Extra QML import paths for Qt Creator's code model" )
But I fail to understand why this is needed if this policy is set to NEW
https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html
as should be by the version requirement:qt_standard_project_setup( REQUIRES 6.8 )
So it's working now, but I' like to understand it a bit more deeply.
Thanks in advance, -
And as a bonus question, I fail to understand why modules are sometimes built as plain modules and sometime as libraries, by adding this (and then linking as a plugin):
qt_add_library( StyleModule STATIC )
In that case, also, is this needed in the main.cpp:
Q_IMPORT_QML_PLUGIN( StyleModulePlugin );
It works with and without, so I'm missing the point.
There are a lot of examples circulating online, for various versions of Qt and all of this has changed quite a lot. The documentation being pretty thick, it's not easy to find up-to-date basic guidelines.Explanation or examples of use cases welcome! Thanks!
-
-
-