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

问题描述 投票:0回答:1

我正在研究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})

UI 文件夹中的 CMakeLists.txt(Main.qml 所在位置)如下所示:

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();
}

我尝试在

NO_PLUGIN
调用中添加
qt_add_qml_module(UI
选项,因为我当前没有使用任何插件或 cpp 文件作为后备目标(如果我正确理解了这个概念),但随后它尝试加载 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

我看到这是

build/UI
文件夹中qmldir的路径

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/qml
    路径实际上在哪里?如何在那里放置模块?我是否需要创建自己的相对于构建/安装目录的路径,还是应该将它们添加到
    qrc:/qt/qml

cmake qml qt6
1个回答
0
投票

在根 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 文件添加到项目中。
© www.soinside.com 2019 - 2024. All rights reserved.