Определение JavaScript-ресурсов в QML
Логика программы для приложения QML может быть определена на JavaScript. JavaScript-код может быть определен непосредственно в документах QML или отделен в JavaScript-файлы (известные как JavaScript Resources в QML).
В QML поддерживаются два разных типа JavaScript-ресурсов: файлы реализации с поддержкой состояния и общие (библиотечные) файлы. Оба типа JavaScript-ресурсов могут быть импортированы другими JavaScript-ресурсами или включены в QML-модули.
Ресурс реализации с поддержкой состояния
Большинство JavaScript-файлов, импортированных в QML-документ, представляют собой реализацию с поддержкой состояния для QML-документа, который их импортирует. В этих случаях каждый экземпляр типа QML-объекта, определенного в документе, требует отдельной копии JavaScript-объектов и состояния для корректной работы.
По умолчанию при импорте JavaScript-файлов создаётся уникальная, изолированная копия для каждого экземпляра QML-компонента. Если этот JavaScript-файл не импортирует какие-либо ресурсы или модули с инструкцией .import, его код будет выполняться в том же пространстве имён, что и экземпляр QML-компонента, и, следовательно, может обращаться к объектам и свойствам, объявленным в этом QML-компоненте и манипулировать ими. В противном случае у него будет своё уникальное пространство имён, и объекты и свойства QML-компонента должны передаваться функциям JavaScript-файла в качестве параметров, если они требуются.
Пример ресурса реализации с поддержкой состояния:
// MyButton.qml
import QtQuick 2.0
import "my_button_impl.js" as Logic // A new instance of this JavaScript resource
// is loaded for each instance of Button.qml.
Rectangle {
id: rect
width: 200
height: 100
color: "red"
MouseArea {
id: mousearea
anchors.fill: parent
onClicked: Logic.onClicked(rect)
}
} // my_button_impl.js
var clickCount = 0; // this state is separate for each instance of MyButton
function onClicked(button) {
clickCount += 1;
if ((clickCount % 5) == 0) {
button.color = Qt.rgba(1,0,0,1);
} else {
button.color = Qt.rgba(0,1,0,1);
}
} В целом, простая логика должна определяться непосредственно в файле QML, но более сложная логика должна быть отделена в ресурсы реализации с поддержкой состояния для обеспечения поддерживаемости и читабельности.
Общие JavaScript-ресурсы (библиотеки)
По умолчанию JavaScript-файлы, импортированные из QML, совместно используют контекст с QML-компонентом. Это означает, что JavaScript-файлы имеют доступ к тем же QML-объектам и могут изменять их. Вследствие этого каждый импорт должен иметь уникальную копию этих файлов.
Предыдущий раздел охватывает импорт JavaScript-файлов с поддержкой состояния. Однако некоторые JavaScript-файлы являются бессостоятельными и ведут себя скорее как многократно используемые библиотеки, предоставляя набор вспомогательных функций, не требующих ничего из места импорта. Можно значительно сэкономить память и ускорить создание экземпляров QML-компонентов, если пометить такие библиотеки специальным предикатом, как показано в следующем примере.
// factorial.js
.pragma library
var factorialCount = 0;
function factorial(a) {
a = parseInt(a);
// factorial recursion
if (a > 0)
return a * factorial(a - 1);
// shared state
factorialCount += 1;
// recursion base-case.
return 1;
}
function factorialCallCount() {
return factorialCount;
} Декларация предикатов должна появляться перед любым JavaScript-кодом, за исключением комментариев.
Обратите внимание, что несколько QML-документов могут импортировать "factorial.js" и вызывать предоставляемые им функции factorial и factorialCallCount. Состояние JavaScript-импорта совместно используется всеми QML-документами, которые его импортируют, и, следовательно, возвращаемое значение функции factorialCallCount может быть не нулевым при вызове внутри QML-документа, который никогда не вызывал функцию factorial.
Например:
// Calculator.qml
import QtQuick 2.0
import "factorial.js" as FactorialCalculator // This JavaScript resource is only
// ever loaded once by the engine,
// even if multiple instances of
// Calculator.qml are created.
Text {
width: 500
height: 100
property int input: 17
text: "The factorial of " + input + " is: " + FactorialCalculator.factorial(input)
} Так как они общие, файлы .pragma library не могут напрямую обращаться к объектам или свойствам экземпляров QML-компонентов, хотя значения QML могут передаваться в качестве параметров функции.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/qtqml-javascript-resources.html