首页 > 解决方案 > 为什么将 qml 文件放入库后无法加载?

问题描述

我的项目如下所示:

.
├── CMakeLists.txt
└── src
    ├── CMakeLists.txt
    ├── main.cpp
    └── radon
        ├── main.qml
        ├── qml.qrc
        ├── radon.cpp
        └── radon.h

src/CMakeList.txt定义了两个目标,一个库和一个链接到该库的可执行文件。

# only relevant code shown
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5 5.15 REQUIRED COMPONENTS Core Quick REQUIRED)
add_library(RadonCore
        radon/radon.h
        radon/radon.cpp
        radon/qml.qrc
        )

target_link_libraries(RadonCore
        PUBLIC Qt5::Core Qt5::Quick)

add_executable(RadonApp
        main.cpp)
target_link_libraries(RadonApp
        PRIVATE RadonCore)

该库仅包含我的应用程序的入口点,main.cpp仅调用该入口。

// header
#ifndef RADON_RADON_H
#define RADON_RADON_H

namespace radon{
    int radon_entry(int argc, char* argv[]);
}

#endif //RADON_RADON_H
// source
#include "radon.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>

int radon::radon_entry(int argc, char* argv[])
{
    // only relevant code shown
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    engine.load(url);

    return QGuiApplication::exec();
}
// main.cpp
#include "radon/radon.h"

int main(int argc, char* argv[])
{
    return radon::radon_entry(argc, argv);
}

使条目独立于的想法main()是,我可以将库链接到具有自己的main(). 但是在配置下,qt报错找不到main.qml

QQmlApplicationEngine failed to load component
qrc:/main.qml: No such file or directory

如果我提供一个main()内部radon.cpp并将其构建为可执行文件,那么它可以正常工作。是什么赋予了?

qml.qrc看起来像这样:

<RCC>
    <qresource prefix="/">
        <file>main.qml</file>
    </qresource>
</RCC>

标签: qtcmakeqmlqtquick2

解决方案


问题是这RadonCore是一个静态库。在 Qt 中,如果静态库使用资源,它必须Q_INIT_RESOURCE在第一次使用之前将宏展开到某处。有关更多信息,请参见此处。请注意,宏不能放置在任何命名空间内(不包括全局命名空间)。所以这个问题的解决方案看起来像这样:

  1. 提取radon_entry到全局命名空间
  2. Q_INIT_RESOURCE(qml)在的第一行放置一个宏调用radon_entry

推荐阅读