Qt 6 qml module and qml import path
-
So I have a qt 6 where I have create a qml module with cmake following wiki. Now no matter what I do I cannot get the engine to pick up on my module in the build dir. If I move my module and the generated files qt creates such as qmldir and qmltypes to the Qt/6.5.1/gcc_64/qml folder it works but no matter what I have tried I get nothing. ANY suggestions what my cause this issue would be much appreciated!
-
So I realized my question was vary abstract. Doing further investigation I am lost on how Qt decides the qml import locations at run time.
For example. If my folder structure is as follows:
MyApp
CMakeLists.txt
MyQmlModule
CMakeList.txtNo problem. dont need to do anything extra the qml module from MyQmlModule is loaded by just linking the library in the MyApp CMakeLists.txt
Now if I add a Orginzation folder between MyApp and MyQmlModule everything breaks.
MyApp
CMakeLists.txt
QmlModules
MyQmlModule
CMakeList.txtTo get it to work in the above structure I need to do two things
- add the CMakeList.txt of the module a QML_IMPORT_PATH to bee the ${CMAKE_CURRENT_BINARY_DIR}/../ it has to be the parent (QmlModules) dir for Qt Creator to pick up on it. This allows syntax completion / highlighting during development
- in main.cpp engine->addImportPath( ${CMAKE_CURRENT_BINARY_DIR})
#2 is my problem I shouldnt have to add this to my production code to just find my qml module. I assumed this would be covered in #1 in the cmake file but doesnt seem to take.
Last thought is, I thought that the qt_add_qml_module function in cmake creates .qrc file that was compiled as part of the the plugin? If thats not true do I need to install all my assets along side the plugin?
-
Here is an example:
Folder Structure:
- testapp
- CMakeLists.txt
- main.cpp
- Main.qml
- modules
- mymodule
- CMakeLists.txt
- CustomQMl.qml
testapp CMakeLists.txt
cmake_minimum_required(VERSION 3.16) project(testapp VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) qt_standard_project_setup(REQUIRES 6.5) qt_add_executable(apptestapp main.cpp ) qt_add_qml_module(apptestapp URI testapp VERSION 1.0 QML_FILES Main.qml ) set_target_properties(apptestapp PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) target_link_libraries(apptestapp PRIVATE Qt6::Quick mymodule ) install(TARGETS apptestapp BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) # adding custom module add_subdirectory(modules/mymodule)
testapp main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; QObject::connect( &engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); // have to add this import path or it wont load module engine.addImportPath( "/home/developer/testapp/builds/" "build-testapp-Desktop_Qt_6_5_1_GCC_64bit-Debug/modules"); engine.loadFromModule("testapp", "Main"); return app.exec(); }
modules/mymodule CMakeLists.txt
cmake_minimum_required(VERSION 3.16) project(MyModuleProject VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) qt_standard_project_setup(REQUIRES 6.5) qt_add_qml_module(mymodule URI mymodule VERSION 1.0 QML_FILES CustomQml.qml ) set_target_properties(mymodule PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) set(QML_DIRS "${QML_IMPORT_PATH}") list(APPEND QML_DIRS "${CMAKE_CURRENT_BINARY_DIR}/../") set(QML_IMPORT_PATH "${QML_DIRS}" CACHE STRING "Controls" FORCE)
as you can see in the example above I need to add the import path at runtime to the build dir to have it find the plugin module and load it. If I cut out the "modules" dir I can remote the line to import qml from the main.cpp and I have to adjust the QML_IMPORT_PATH to be just the ${CAMKE_CURRENT_BINART_DIR} for qt creator to pick up on it. I believe the problem to be that the QML_IMPORT_PATH is set differently between qt creator and runtime there for my QML_IMPORT_PATH I added in the cmake is not even used during runtime. I have checked my qt creator settings and yes that carry over env variable from the build env to the runtime which would include QML_IMPORT_PATH. In the past I would something like this in the main.cpp Q_INIT_RESOURCE(pathtoqrcfile.qrc) and then add the qrc:/.... as the qml import path. This to me is acceptable because I know when I release I will release with that qrc not the build dir as its doing with qt 6.5.
- testapp