Reputation: 391
If I use import MyModule 1.0
I got an error message what MyModule is not installed.
QQmlApplicationEngine failed to load component
qrc:/main.qml:3:1: module "MyModule" is not installed
But I correctly wrote qmldir file and resources file.
And if I use import "MyModule"
all is Ok. But I need to use import without quotes and import my modules in all files in different dirrectories. How to correctly import custom Qml element?
File structure
QMLDIRTEST
│ CMakeLists.txt
│ main.cpp
│ main.qml
│ qml.qrc
│
└───MyModule
qmldir
RedRectangle.qml
CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(QmlDirTest VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt5 COMPONENTS Core Quick REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick REQUIRED)
set(PROJECT_SOURCES main.cpp qml.qrc)
add_executable(QmlDirTest ${PROJECT_SOURCES})
target_link_libraries(QmlDirTest PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick)
qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>MyModule/RedRectangle.qml</file>
<file>MyModule/qmldir</file>
</qresource>
</RCC>
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
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.addImportPath("qrc:/Ui");
engine.load(url);
return app.exec();
}
main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import MyModule 1.0
//import "MyModule"
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
RedRectangle { anchors.centerIn: parent }
}
RedRectangle.qml
import QtQuick 2.15
Rectangle {
width: 200
height: 100
color: "red"
}
qmldir
Module MyModule
RedRectangle 1.0 RedRectangle.qml
Upvotes: 2
Views: 1433
Reputation: 984
According to the documentation, addImportPath
is needed to tell the engine where to search for the new modules that you have provided.
QQmlEngine::addImportPath states:
Adds a path as a directory where the engine searches for installed modules in a URL-based directory structure. The path may be a local filesystem directory, a Qt Resource path (
:/imports
), a Qt Resource URL (qrc:/imports
), or a URL.
After Qt 6.*, there is a qt_add_qml_module
function in CMake that you can use to add new modules using only CMake. This function will automatically generate the qmldir
and resource files.
qt_add_qml_module(${PROJECT_NAME}
URI module.uri
QML_FILES Component1.qml Component2.qml
)
In Qt 6.*, there is a qrc:/qt/qml
in the default import path list. By using qt_policy(SET QTP0001 NEW)
in your CMake file, the generated resources (using qt_add_qml_module
) will have /qt/qml
as their default prefix. This allows the engine to detect your module without needing to add any new import paths. (ref: QTP0001)
You can check this by printing engine.importPathList()
, and you will see qrc:/qt/qml
in the output list.
qDebug << engine.importPathList();
// Output:
// ("path/to/build-directory/", "path/to/Qt/6.6.1/current-kit/qml", "qrc:/qt-project.org/imports", "qrc:/qt/qml")
You can use the same trick in Qt 5 as well.
By printing importPathList
, you will see that there is /qt-project.org/imports
as the default resource path in the import path list:
qDebug << engine.importPathList();
// Output:
QList(
"path/to/build-directory/",
"path/to/Qt/5.15.2/current-kit/qml",
"qrc:/qt-project.org/imports",
)
So, by adding /qt-project.org/imports
to your resource prefix, you can make the engine recognize your provided module. For example:
qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
<qresource prefix="/qt-project.org/imports">
<file>MyModule/RedRectangle.qml</file>
<file>MyModule/qmldir</file>
</qresource>
</RCC>
To ensure that the linter recognizes your modules, you can also set the QML_IMPORT_PATH
variable in your CMake file.
list(APPEND QML_DIRS "${CMAKE_SOURCE_DIR}/.")
set(QML_IMPORT_PATH "${QML_DIRS}" CACHE STRING "Qt Creator extra qml import paths")
Upvotes: 1