qt6 Cmake как создать в проекте qml singleton

Рейтинг: 1Ответов: 2Опубликовано: 01.05.2023

никак не могу создать простой qml singleton в проекте. Вот структура моего проекта:

- CMakeLists.txt
- main.cpp
- Main.qml
- StyleSettings
- CMakeLists.txt
- Style.qml
- qmldir

В main.cpp:

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

    QQmlApplicationEngine engine;
    engine.addImportPath(u"qrc:/StyleSettings/Style.qml"_qs);
    const QUrl url(u"qrc:/MyAdressBook/Main.qml"_qs);
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
        &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

Main.qml:

import QtQuick
import QtQuick.Window
import StyleSettings 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Rectangle {
        id: _background
        z: -100
        anchors.fill: parent
        color: Style.backgroundColor
        opacity: Style.emphasisOpacity
    }
}

Style.qml:

pragma Singleton
import QtQuick

QtObject {
    property bool isDarkTheme: true
    readonly property color primaryColor: isDarkTheme ? "#BB86FC" : "#6200EE"
    readonly property color primaryVariantColor: "#3700B3"
    readonly property color secondaryColor: "#03DAC6"
    readonly property color secondaryVariant: isDarkTheme ? "#018786" : secondaryColor
    readonly property color backgroundColor: isDarkTheme ? "#121212" : "#FFFFFF"
    readonly property color errorColor: isDarkTheme ? "#CF6679" : "#B00020"
    readonly property color textColor: isDarkTheme ? "#FFFFFF" : "#000000"
    readonly property color themeDefaultColor: isDarkTheme ? "#000000" : "#FFFFFF"
    readonly property color themeInvertedColor: isDarkTheme ? "#FFFFFF" : "#000000"

    readonly property real defaultOpacity: 1
    readonly property real emphasisOpacity: 0.87
    readonly property real secondaryOpacity: 0.6
    readonly property real disabledOpacity: 0.38

    readonly property int defaultOffset: 15
    readonly property int mediumOffset: 10
    readonly property int tinyOffset: 5

    readonly property int bigSpacing: 20
    readonly property int mediumSpacing: 10
    readonly property int smallSpacing: 7
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)

project(MyAdressBook VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 6.2 REQUIRED COMPONENTS Quick)


qt_add_executable(appMyAdressBook
    main.cpp
)

qt_add_qml_module(appMyAdressBook
    URI MyAdressBook
    VERSION 1.0
    QML_FILES Main.qml
)

add_subdirectory(StyleSettings)

set_target_properties(appMyAdressBook PROPERTIES

    MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com

    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}

    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}

    MACOSX_BUNDLE TRUE

    WIN32_EXECUTABLE TRUE
)

target_link_libraries(appMyAdressBook
    PRIVATE Qt6::Quick
)

#install(TARGETS StyleSettings)

install(TARGETS appMyAdressBook

    BUNDLE DESTINATION .

    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

StyleSettings/CMakeLists.txt:

qt_add_qml_module(StyleSettings

    URI "StyleSettings"

    VERSION 1.0

    QML_FILES

        Style.qml
    )

Компилятор выдает ошибку:

QQmlApplicationEngine failed to load component qrc:/MyAdressBook/Main.qml:3:1: Die Bibliothek F:\Qml_proj\MyCmakeAdressBook\build-MyAdressBook-Desktop_Qt_6_3_2_MSVC2019_64bit-Debug\StyleSettings\StyleSettingsplugin.dll kann nicht geladen werden: Не найден указанный модуль.

Ответы

▲ 1

Qt6 при сборке автоматически генерирует файл qmldir с описаниями всех типов qml. Чтобы использовать синглетоны, нужно в qmldir пометить, что соответствующие типы являются синглетонами. Для этого в CMakeLists.txt нужно добавить строчку:

set_source_files_properties(Style.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)

Причём эта строчка должна быть до вызова qt_add_qml_modules. После этого файл можно импортировать как любой другой qml файл и использовать

// Main.qml
import QtQuick
import QtQuick.Window
// import Style писать не нужно. Если Style.qml лежит
// не в той же папке, где Main.qml, например в ./styles/Style.qml,
// нужно импортировать эту папку: import "./styles"

Window {
  color: Style.color
}
▲ 0

Синглтон можно создать несколькими способами:

  • Непосредственно в QML:
    Для этого нужно в самом qml-файле объявить его с помощью директивы
    pragma Singleton и добавить его в qmldir (singleton Alias 1.0 File.qml).
  • Из Плюсов:
    • Либо макросом QML_SINGLETON
    • Либо функцией qmlRegisterSingletonInstance