在没有IDE的情况下使用CMake构建QML应用程序时,QQmlApplicationEngine无法加载组件

QQmlApplicationEngine failed to load component when building QML app with CMake without IDE

提问人:Daniel Beliavskij 提问时间:11/15/2023 更新时间:11/17/2023 访问量:45

问:

我正在研究QML应用程序。目前,此应用程序仅包含不同的QML文件和一个仅具有main功能的main.cpp文件。稍后,我还将向其添加业务逻辑。

我正在使用 CMake 构建应用程序,而无需使用任何 IDE。

我的应用程序构建和链接没有问题,但是当我尝试运行应用程序时,它总是无法加载Main.qml并启动应用程序。

qt.qml.import: addImportPath: "/home/username/Qt/6.5.3/gcc_64/qml"
qt.qml.import: addImportPath: "qrc:/qt/qml"
qt.qml.import: addImportPath: "qrc:/qt-project.org/imports"
qt.qml.import: addImportPath: "/home/username/Project/ApplicationProject/build"
qt.qml.import: addLibraryImport:  "UI" version ' invalid ' as ""
qt.qml.import: importExtension:  loaded "/home/username/Project/ApplicationProject/build/UI/qmldir"
qt.qml.import: resolvePlugin Could not resolve dynamic plugin with base name "UIplugin" in "/home/username/Project/ApplicationProject/build/UI"  file does not exist
qt.qml.import: locateLocalQmldir: UI module's qmldir found at ""
qt.qml.import: LoadHelper: Errors loading  "UI" QList(file:///home/username/Project/ApplicationProject/build/UI/qmldir: module "UI" plugin "UIplugin" not found)
QQmlApplicationEngine failed to load component
<Unknown File>: No module named "UI" found

我已经设置了详细的输出export QML_IMPORT_TRACE=1

我的简化根 CMakeLists.txt 文件如下所示:

cmake_minimum_required(VERSION 3.20)

project(App VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Quick Gui QuickControls2 Qml Svg)
qt_standard_project_setup(REQUIRES 6.5)

qt_add_executable(App
    src/main.cpp
)

add_subdirectory(UI)

target_link_libraries(App PRIVATE Qt6::Quick Qt6::Gui Qt6::QuickControls2 Qt6::Svg Qt6::Qml)
target_link_libraries(App PRIVATE UI)

if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    set(CMAKE_INSTALL_PREFIX "/usr/lib/" CACHE PATH "..." FORCE)
endif()

install(TARGETS App
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

qt_generate_deploy_qml_app_script(
    TARGET App
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
    DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM
)

install(SCRIPT ${deploy_script})

放置 Main.qml 的 UI 文件夹中的 CMakeLists.txt 如下所示:

qt_add_qml_module(UI
    URI UI
    NO_PLUGIN
    VERSION 1.0
    QML_FILES
        Main.qml
)

target_link_libraries(UI PUBLIC
    OtherQML1
    OtherQML2
    OtherQML3
    OtherQML4
)

add_subdirectory(OtherQML1)
add_subdirectory(OtherQML2)
add_subdirectory(OtherQML3)
add_subdirectory(OtherQML4)

还有我的main.cpp文件,它位于src目录的根项目文件夹中:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQuickStyle::setStyle("Universal");

    QQmlApplicationEngine engine;
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
        &app, []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("UI", "Main");

    return app.exec();
}

我尝试添加要调用的选项,因为我目前没有使用任何插件或 cpp 文件作为后备目标(如果我正确理解了这个概念),但随后它尝试加载 Main.qml 但找不到它:NO_PLUGINqt_add_qml_module(UI

qt.qml.import: addImportPath: "/home/username/Qt/6.5.3/gcc_64/qml"
qt.qml.import: addImportPath: "qrc:/qt/qml"
qt.qml.import: addImportPath: "qrc:/qt-project.org/imports"
qt.qml.import: addImportPath: "/home/username/Project/ApplicationProject/build"
qt.qml.import: addLibraryImport:  "UI" version ' invalid ' as ""
qt.qml.import: importExtension:  loaded "/home/username/Project/ApplicationProject/build/UI/qmldir"
qt.qml.import: resolvePlugin Could not resolve dynamic plugin with base name "UIplugin" in "/home/username/Project/ApplicationProject/build/UI"  file does not exist
qt.qml.import: locateLocalQmldir: UI module's qmldir found at ""
qt.qml.import: LoadHelper: Errors loading  "UI" QList(file:///home/username/Project/ApplicationProject/build/UI/qmldir: module "UI" plugin "UIplugin" not found)
QQmlApplicationEngine failed to load component
<Unknown File>: No module named "UI" found

我看到这是文件夹中qmldir中的路径build/UI

module UI
typeinfo UI.qmltypes
prefer :/qt/qml/UI/
Main 1.0 Main.qml

在我拥有的同一个文件夹中,它将别名定义为正确的路径:build/UI/UI_qml_module_dir_map.qrc

<RCC>
  <qresource prefix="/">
    <file alias="/qt/qml/UI">/home/username/Project/ApplicationProject/build/UI</file>

  </qresource>
</RCC>

我的问题是:

  1. 我该如何解决这个问题,原因是什么?是由于我的文件夹结构吗?

  2. 有人可以参考我一些解释 QT 追索系统 (qrc) 等的来源吗?我正在阅读文档,似乎可以掌握这个概念。路径到底在哪里?如何将模块放置在那里?我是否需要创建自己的相对于我的构建/安装目录的路径,或者我应该将它们添加到?qrc:/qt/qmlqrc:/qt/qml

CMake QML QT6

评论

0赞 JarMan 11/16/2023
他们在博客中描述了导入路径。qrc:/qt/qml
0赞 Daniel Beliavskij 11/17/2023
谢谢,我认为它为我澄清了这个概念

答:

1赞 Mohsen Kondori 11/17/2023 #1

在根 CMakeLists.txt 更改为target_link_libraries(App PRIVATE UI)target_link_libraries(App PRIVATE UIplugin)

main.cpp:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    QQuickStyle::setStyle("Universal");
    engine.addImportPath(":/");

    QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
        &app, []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("UI", "Main");

    return app.exec();
}

UI 文件夹中的 CMakeLists.txt

qt_add_qml_module(UI
        URI UI
        VERSION 1.0
        QML_FILES
            Main.qml
    )
    
    add_subdirectory(OtherQML1)
    add_subdirectory(OtherQML2)
    add_subdirectory(OtherQML3)
    add_subdirectory(OtherQML4)
    
    target_link_libraries(UI PUBLIC
        OtherQML1plugin
        OtherQML2plugin
        OtherQML3plugin
        OtherQML4plugin
    )
  • 删除 .qrc 文件并使用 cmakelist 将 qml 文件添加到项目中。

评论

0赞 Daniel Beliavskij 11/17/2023
但有一件事,我最初无法链接到所有其他内容。所以我需要添加到我所有的调用参数中,因为它一开始给了我一个错误,它无法链接到模块库UIpluginqt_add_qml_moduleSTATIC