Хост-среда JavaScript в QML
QML предоставляет хост-среду JavaScript, предназначенную для написания приложений QML. Эта среда отличается от хост-среды, предоставляемой браузером, или среды JavaScript на серверной стороне, такой как Node.js. Например, QML не предоставляет объект window
или DOM API, которые обычно встречаются в среде браузера.
Общая база
Подобно браузеру или среде JavaScript на стороне сервера, среда выполнения QML реализует стандарт спецификации языка ECMAScript. Это обеспечивает доступ ко всем встроенным типам и функциям, определенным стандартом, таким как Object
, Array
и Math
. Среда выполнения QML реализует 7-е издание стандарта.
Оператор нулевого слияния (начиная с Qt 5.15) и оператор опциональной последовательности (начиная с Qt 6.2) также реализованы в среде выполнения QML.
Стандартные встроенные модули ECMAScript явно не описаны в документации QML. Дополнительную информацию об их использовании смотрите в стандарте ECMA-262 7-го издания или на одном из множества онлайн-справочников и учебных пособий по JavaScript, таких как Справочник по JavaScript W3Schools (раздел Справочник по объектам JavaScript). Многие сайты сосредоточены на JavaScript в браузере, поэтому в некоторых случаях вам может потребоваться дважды проверить спецификацию, чтобы определить, является ли данная функция или объект частью стандартного ECMAScript или характерна для среды браузера. В случае приведенной выше ссылки W3Schools раздел «Справочник по объектам JavaScript» обычно охватывает стандарт, в то время как разделы «Справочник по объектам браузера» и «Справочник по объектам HTML DOM» зависят от браузера (и, следовательно, не применимы к QML).
Аннотации и утверждения типов
Объявления функций могут и должны содержать аннотации типов. Аннотации типа добавляются к объявлению аргументов и к самой функции для аннотации возвращаемого типа. Следующая функция принимает параметры int
и string
и возвращает QtObject
:
function doThings(a: int, b: string) : QtObject { ... }
Аннотации типов помогают таким инструментам, как Qt Creator и qmllint, понимать код и обеспечивать лучшую диагностику. Более того, они упрощают использование функций из C++. Дополнительные сведения см. в разделе «Взаимодействие с объектами QML из C++».
Утверждения типа (иногда называемые as-casts) также могут использоваться для приведения объекта к другому типу объекта. Если объект на самом деле имеет заданный тип, то утверждение типа возвращает тот же самый объект. Если нет, оно возвращает null
. В следующем фрагменте мы утверждаем, что объект parent
является Rectangle
, прежде чем получить доступ к определенному его члену.
Item {
property color parentColor: (parent as Rectangle)?.color || "red"
}
Опциональная цепочка (?.
) позволяет избежать создания исключения, если parent
на самом деле не является Rectangle
. В этом случае в качестве parentColor
выбирается "red"
.
Глобальный объект QML
Хост-среда QML JavaScript реализует ряд хост-объектов и функций, как подробно описано в документации QML Global Object.
Эти хост-объекты и функции доступны всегда, независимо от того, были ли импортированы какие-либо модули.
Объекты и функции JavaScript
Список объектов, функций и свойств JavaScript, поддерживаемых движком QML, можно найти в Списке объектов и функций JavaScript.
Обратите внимание, что QML вносит следующие изменения в собственные объекты:
- В прототип
String
добавлена функцияarg()
. - В прототипы
Date
иNumber
добавлены функции преобразования с учетом локали.
Кроме того, QML также расширяет поведение функции instanceof
, позволяя выполнять проверку типов по типам QML. Это означает, что вы можете использовать её для проверки того, что переменная действительно имеет тип, который вы ожидаете, например:
var v = something();
if (!v instanceof Item) {
throw new TypeError("I need an Item type!");
}
...
Ограничения среды JavaScript
QML реализует следующие ограничения для кода JavaScript:
- Код JavaScript, написанный в файле .qml, не может изменять глобальный объект. Код JavaScript в файле .js может изменять глобальный объект, и эти изменения будут видны в файле .qml при импорте.
В QML глобальный объект является константным – существующие свойства нельзя изменить или удалить, а новые свойства нельзя создать.
Большинство программ JavaScript не изменяют намеренно глобальный объект. Однако автоматическое создание JavaScript необъявленных переменных является неявной модификацией глобального объекта и запрещено в QML.
Предполагая, что переменная a
не существует в цепочке областей видимости, следующий код недопустим в QML:
// Недопустимая модификация необъявленной переменной
a = 1;
for (var ii = 1; ii < 10; ++ii)
a = a * ii;
console.log("Result: " + a);
Его можно тривиально изменить на следующий корректный код.
var a = 1;
for (var ii = 1; ii < 10; ++ii)
a = a * ii;
console.log("Result: " + a);
Любая попытка изменить глобальный объект – явно или неявно – вызовет исключение. Если его не поймать, это приведет к печати предупреждения, которое включает в себя файл и номер строки кода с нарушением.
- Глобальный код запускается в уменьшенной области видимости.
Если во время запуска файл QML включает внешний файл JavaScript с «глобальным» кодом, он выполняется в области видимости, которая содержит только сам внешний файл и глобальный объект. То есть у него не будет доступа к объектам и свойствам QML, как обычно.
Допускается глобальный код, который обращается только к локальным переменным скрипта. Это пример допустимого глобального кода.
var colors = [ "red", "blue", "green", "orange", "purple" ];
Глобальный код, обращающийся к объектам QML, не будет работать правильно.
// Недопустимый глобальный код - переменная "rootObject" не определена
var initialPosition = { rootObject.x, rootObject.y }
Это ограничение существует, поскольку среда QML еще не полностью установлена. Чтобы запустить код после завершения настройки среды, смотрите раздел «JavaScript в коде запуска приложения».
- Значение
this
не определено в QML в большинстве контекстов.
Ключевое слово this
поддерживается при связывании свойств из JavaScript. В выражениях привязки QML, обработчиках сигналов QML и объявленных функциях QML this
относится к объекту области видимости. Во всех других ситуациях значение this
в QML не определено.
Чтобы сослаться на конкретный объект, укажите его id
. Например:
Item {
width: 200; height: 100
function mouseAreaClicked(area) {
console.log("Clicked in area at: " + area.x + ", " + area.y);
}
// Это передаст area в функцию
MouseArea {
id: area
y: 50; height: 50; width: 200
onClicked: mouseAreaClicked(area)
}
}