Хост-среда JavaScript в QML

Добавлено 11 мая 2022 в 02:51

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)
    }
}

Теги

GUI / Графический интерфейс пользователяJavaScriptQMLQtQtQuickПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.