Объявить глобальное свойство в QML для других файлов QML
Я хочу объявить глобальное свойство в файле конфигурации и использовать его в других файлах. например, объявить mainbg
в:
Style.qml
property color mainbg: 'red'
и использовать его в других файлах QML (например, view.qml
и main.qml
). Как я могу выполнить эту работу?
Ответы
Ответ 1
Используйте синглтон QML.
Пожалуйста, обратитесь к разделу "Подход 2" на этой странице
- Уродливые QTBUG-34418 комментарии мои.
Это те части, которые вам нужны:
Style.qml
pragma Singleton
import QtQuick 2.0
QtObject {
property color mainbg: 'red'
}
qmldir
Этот файл должен находиться в той же папке, что и файл singleton.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-project (см. QTBUG-34418, для синглтонов требуется явный импорт для загрузки qmldir файла).
Ответ 2
В принципе, если вам не нужна привязка к свойствам (если вы являетесь константой и не нуждаетесь в уведомлении об изменении), вы можете определить ее в общей библиотеке Javascript, например:
// MyConstants.js
.pragma library
var mainbg = "red";
И используйте его в QML следующим образом:
import "MyConstants.js" as Constants
Rectangle {
color: Constants.mainbg;
}
Но плохая сторона этого:
- нет сильной типизации (JS действительно не знает о типах), поэтому вы можете поместить что угодно, даже если это не цвет.
- и если вы измените mainbg
, элемент, использующий его, не будет уведомлен об изменении и сохранит старое значение
Итак, если вам нужна проверка типов и привязка/изменение уведомления, просто объявите свое свойство как член корневого объекта в вашем main.qml, и он будет доступен извне в приложении QML, поскольку это свойство будет фактически быть непосредственно зарегистрированным в объекте Qml Context, который по определению является глобальным.
Надеюсь, что это поможет.
Ответ 3
Вы можете создать файл 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
}
}
Ответ 4
Добавив некоторый вклад в ответ @pixelgrease, я нашел другой метод, который не требует относительного import "."
пути import "."
, обойти ошибку QTBUG-34418. Это особенно полезно, если у qmldir
есть qmldir
и singleton в другом месте, чем файл 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 для справки.
Ответ 5
Добавьте это свойство в main, и вы можете получить к нему доступ в любом qml, это может быть неправильным, но это работает.
или если вы хотите сгруппировать свойство, добавьте их в qml
включите этот qml в main и дайте id, теперь вы можете получить доступ к этому свойству, используя этот id
main.qml
Item{
width:10
height:10
Model{
id:globdldata
}
}
Model.qml
Item {
property color mainbg: 'red'
}
вы можете использовать globdldata.mainbg где угодно
Ответ 6
Вы всегда можете создать новый объектный файл QML, который содержит свойства, которые вы хотите использовать совместно с qml файлами. Просто импортируйте его так же, как и любой объект QML, и у вас будет доступ к свойствам. Теперь, если вы хотите иметь возможность изменять эти свойства и иметь общие для всех изменения, все становится намного сложнее, и вы, скорее всего, захотите прибегнуть к каким-то решениям, используя js файлы .pragma library. Если вы не хотите писать какую-то альтернативу С++.