Определение ресурсов JavaScript в QML

Добавлено 10 мая 2022 в 22:41

Логика программы для приложения QML может быть определена в JavaScript. Код JavaScript может быть определен как встроенный в документы QML или разделен на файлы JavaScript (известные как ресурсы JavaScript в 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 // Новый экземпляр этого ресурса JavaScript
                                    // загружается для каждого экземпляра MyButton.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;   // это состояние отдельно для каждого экземпляра 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, если пометите такие библиотеки специальной инструкцией pragma, как показано в следующем примере.

// factorial.js
.pragma library

var factorialCount = 0;

function factorial(a) {
    a = parseInt(a);

    // рекурсия factorial
    if (a > 0)
        return a * factorial(a - 1);

    // общее состояние
    factorialCount += 1;

    // базовый вариант рекурсии
    return 1;
}

function factorialCallCount() {
    return factorialCount;
}

Объявление pragma должно стоять перед любым кодом JavaScript, за исключением комментариев.

Обратите внимание, что импортировать "factorial.js" и вызывать предоставляемые им функции factorial и factorialCallCount могут несколько документов QML. Состояние импорта JavaScript является общим для документов QML, которые его импортируют, поэтому возвращаемое значение функции factorialCallCount может быть ненулевым при вызове в документе QML, который никогда не вызывал функцию factorial.

Например:

// Calculator.qml
import QtQuick 2.0
import "factorial.js" as FactorialCalculator // Этот ресурс JavaScript загружается
                                             // движком только один раз,
                                             // даже если было создано несколько
                                             // экземпляров Calculator.qml

Text {
    width: 500
    height: 100
    property int input: 17
    text: "The factorial of " + input + " is: " + FactorialCalculator.factorial(input)
}

Поскольку файлы .pragma library являются общими, они не могут напрямую обращаться к объектам или свойствам экземпляров компонента QML, хотя значения QML можно передавать в качестве параметров функции.

Теги

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

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

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