Объявить глобальное свойство в QML для других файлов QML

Я хочу объявить глобальное свойство в файле конфигурации и использовать его в других файлах. например объявить mainbg в:

Style.qml:

property color mainbg: 'red'

и использовать его в других файлах QML (например, view.qml а также main.qml). Как я могу сделать эту работу?

7 ответов

Решение

Используйте синглтон QML.

Пожалуйста, обратитесь к " Подходу 2" на этой странице - Уродливые комментарии QTBUG-34418 мои.

Это те части, которые вам нужны:

Style.qml

pragma Singleton
import QtQuick 2.0
QtObject {
    property color mainbg: 'red'
}

qmldir

Этот файл должен находиться в той же папке, что и одиночный файл.qml (Style.qml в нашем примере) или вы должны дать относительный путь к нему. qmldir может также потребоваться включить файл ресурсов.qrc. Более подробную информацию о файлах qmldir можно найти здесь.

# qmldir
singleton Style Style.qml

Как ссылаться

import QtQuick 2.0
import "."  // this is needed when referencing singleton object from same folder
Rectangle {
    color: Style.mainbg  // <- there it is!!!
    width: 240; height 160
}

Этот подход доступен с Qt5.0. Вам нужна папка import заявление, даже если ссылка на синглтон QML в той же папке. Если это та же папка, используйте: import "." Это ошибка, которую я задокументировал на странице qt-проекта (см. QTBUG-34418, синглтоны требуют явного импорта для загрузки файла qmldir).

По сути, если вам не нужно привязывать свойства (если вы используете константу и не должны уведомлять об изменениях), вы можете определить ее в разделяемой библиотеке Javascript, например так:

// MyConstants.js
.pragma library
var mainbg = "red";

И используйте его в QML следующим образом:

import "MyConstants.js" as Constants

Rectangle {
     color: Constants.mainbg;
}

Но есть и плохая сторона: - нет строгой типизации (JS на самом деле не знает о типах), поэтому вы можете поместить что-нибудь, даже если это не цвет. - и если вы измените mainbgТовар, использующий его, не будет уведомлен об изменении и сохранит старое значение

Поэтому, если вам нужна проверка типа и уведомление о связывании / изменении, просто объявите свое свойство как член корневого объекта в вашем main.qml, и оно будет доступно из любого места в приложении QML, потому что свойство фактически будет непосредственно зарегистрировано в объект контекста Qml, который является глобальным по определению.

Надеюсь, поможет.

Вы можете создать файл js и импортировать его во все файлы, которые должны использовать это свойство.

JS файл:

//Note: you only need '.pragma library' if you are planning to
//change this variable from multiple qml files
.pragma library
var globalVariable = 20;

qml файл:

import "test.js" as Global

Rectangle {
  id: main
  width: 300; height: 400

  Component.onCompleted: {
    console.log( Global.globalVariable)
    //you can also change it
    Global.globalVariable = 5
  }
}

Добавляя некоторый вклад в ответ @pixelgrease, я нашел другую технику, которая не требует относительного пути import ".", обойти ошибку QTBUG-34418. Это полезно, особенно если qmldir и класс синглтона в другом месте, чем файл qml, где используется синглтон. Техника требует определения правильного модуля внутри древовидной структуры: модуль затем разрешается путем добавления родительского пути к модулю QML с помощью QmlEngine::addImportPath(moduleParentPath), Например:

qml/
├── <ModuleName>/
│ ├── <ClassName>.qml
│ ├── qmldir

В main.cpp у вас есть то:

QQmlApplicationEngine engine;
engine.addImportPath("qrc:/qml");    // Can be any directory
engine.load("qrc:/qml/main.qml");

Если вы используете ресурсы, qml.qrc:

<RCC>
 <qresource prefix="/">
      (...)
 <file>qml/main.qml</file>
 <file>qml/MySingletons/MySingleton.qml</file>
 <file>qml/MySingletons/qmldir</file>
 </qresource>
</RCC>

В qmldir:

module MySingletons
singleton MySingleton 1.0 MySingleton.qml

В main.qml или любом другом файле qml в другом каталоге:

import MySingletons 1.0

Затем вы используете класс MySingleton как обычно. Я приложил пример MySingletonWithModule.7z к ошибке QTBUG-34418 для справки.

Добавьте это свойство в main, и вы сможете получить к нему доступ в любом qml, это может быть неправильно, но это работает.

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

main.qml

 Item{
 width:10
 height:10

 Model{
 id:globdldata
 }



 }

Model.qml

Item {

property color mainbg: 'red'

}

вы можете использовать globdldata.mainbg где угодно

Начиная с Qt 6.2 с CMake, существует свойство QT_QML_SINGLETON_TYPE, которое позволяет легко использовать синглтоны QML без импорта и qmldir.

Если у вас есть Style.qml

      pragma Singleton
import QtQuick 2.0

QtObject {
    property color mainbg: 'red'
}

Установите это дополнительное свойство в CMakeList.txt.

      set_source_files_properties(Style.qml PROPERTIES
    QT_QML_SINGLETON_TYPE TRUE
)

Использование в других файлах

      Rectangle {
    color: Style.mainbg
}

Вы всегда можете создать новый объектный файл QML, содержащий свойства, которые вы хотите использовать совместно с файлами qml. Просто импортируйте его так же, как любой объект QML, и у вас есть доступ к свойствам. Теперь, если вы хотите иметь возможность изменять эти свойства и делиться изменениями между экземплярами, все становится намного сложнее, и вы, скорее всего, захотите прибегнуть к какому-либо решению с использованием js-файлов библиотеки.pragma. Если только вы не хотите написать какую-то альтернативу C++.

Другие вопросы по тегам