Почему файлы qml не загружаются после того, как я превратил их в библиотеку? - PullRequest
0 голосов
/ 03 августа 2020

Мой проект выглядит следующим образом:

.
├── 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>

1 Ответ

0 голосов
/ 03 августа 2020

Проблема в том, что RadonCore - это статическая c библиотека. В Qt, если библиотека stati c использует ресурсы, она должна где-нибудь развернуть макрос Q_INIT_RESOURCE перед первым использованием. Подробнее см. здесь . Обратите внимание, что макрос не может быть помещен в какое-либо пространство имен (за исключением глобального пространства имен). Таким образом, решение этой проблемы будет выглядеть так:

  1. извлечь radon_entry в глобальное пространство имен
  2. поместите вызов макроса Q_INIT_RESOURCE(qml) в первую строку radon_entry
...