Spec-Zone.ru › Qt 6.0

JavaScript-выражения в документах QML

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

Среда выполнения JavaScript, предоставляемая QML, более строгая, чем в веб-браузере. Например, в QML нельзя добавлять или изменять члены глобального объекта JavaScript. В обычном JavaScript это можно сделать случайно, используя переменную без её объявления. В QML это вызовет исключение, поэтому все локальные переменные должны быть явно объявлены. См. Ограничения среды выполнения JavaScript для получения полного описания ограничений на код JavaScript, выполняемый из QML.

Различные части документов QML могут содержать JavaScript-код:

  1. Тело связей свойств. Эти JavaScript-выражения описывают взаимосвязь между свойствами свойств объекта QML. При изменении зависимостей свойства оно также автоматически обновляется в соответствии с заданной зависимостью.
  2. Тело обработчиков сигналов. Эти JavaScript-операторы автоматически вычисляются всякий раз, когда объект QML генерирует соответствующий сигнал.
  3. Определение пользовательских методов. Функции JavaScript, определённые в теле объекта QML, становятся методами этого объекта.
  4. Самостоятельные файлы ресурсов JavaScript (.js). Эти файлы фактически отделены от документов QML, но их можно импортировать в документы QML. Функции и переменные, определённые в импортированных файлах, могут быть использованы в связях свойств, обработчиках сигналов и пользовательских методах.

JavaScript в связях свойств

В следующем примере свойство color прямоугольника зависит от свойства pressed обработчика нажатий. Эта зависимость описывается с помощью условного выражения:

import QtQuick 2.12

Rectangle {
    id: colorbutton
    width: 200; height: 80;

    color: inputHandler.pressed ? "steelblue" : "lightsteelblue"

    TapHandler {
        id: inputHandler
    }
}

Фактически, в определении связи свойств можно использовать любое JavaScript-выражение (насколько оно сложно), при условии, что результат выражения является значением, тип которого можно присвоить свойству. Это включает побочные эффекты. Однако сложные связи и побочные эффекты не рекомендуются, так как они могут снизить производительность, удобочитаемость и поддерживаемость кода.

Существует два способа определения связи свойств: наиболее распространённый показан в предыдущем примере, в инициализации свойств. Второй (и гораздо более редкий) способ — присвоить свойству функцию, возвращаемую функцией Qt.binding(), из императивного кода JavaScript, как показано ниже:

import QtQuick 2.12

Rectangle {
    id: colorbutton
    width: 200; height: 80;

    color: "red"

    TapHandler {
        id: inputHandler
    }

    Component.onCompleted: {
        color = Qt.binding(function() { return inputHandler.pressed ? "steelblue" : "lightsteelblue" });
    }
}

См. документацию по связям свойств для получения дополнительной информации о том, как определять связи свойств, и документацию по присваиванию свойств по сравнению со связыванием свойств для получения информации о том, чем связи отличаются от присвоения значений.

JavaScript в обработчиках сигналов

Типы объектов QML могут генерировать сигналы в ответ на определённые события. Эти сигналы могут обрабатываться функциями-обработчиками сигналов, которые могут быть определены клиентами для реализации пользовательской логики программы.

Предположим, что кнопка, представленная типом Rectangle, имеет TapHandler и метку Text. TapHandler генерирует свой сигнал tapped при нажатии на кнопку. Клиенты могут реагировать на сигнал в обработчике onTapped с помощью JavaScript-выражений. Двигатель QML выполняет эти JavaScript-выражения, определённые в обработчике, по мере необходимости. Обычно обработчик сигнала связывается с JavaScript-выражениями для инициирования других событий или присвоения значений свойств.

import QtQuick 2.12

Rectangle {
    id: button
    width: 200; height: 80; color: "lightsteelblue"

    TapHandler {
        id: inputHandler
        onTapped: {
            // arbitrary JavaScript expression
            console.log("Tapped!")
        }
    }

    Text {
        id: label
        anchors.centerIn: parent
        text: inputHandler.pressed ? "Pressed!" : "Press here!"
    }
}

Дополнительную информацию о сигналах и обработчиках сигналов см. в следующих разделах:

  • Система событий сигналов и обработчиков
  • Атрибуты объекта QML

JavaScript в автономных функциях

Логика программы также может быть определена в JavaScript-функциях. Эти функции могут быть определены встраиваемо в документы QML (как пользовательские методы) или внешне в импортированных JavaScript-файлах.

JavaScript в пользовательских методах

Пользовательские методы могут быть определены в документах QML и могут вызываться из обработчиков сигналов, связей свойств или функций в других объектах QML. Такие методы часто называют встроенными JavaScript-функциями, потому что их реализация включена в определение типа объекта QML (документ QML), а не во внешнем файле JavaScript.

Пример встроенного пользовательского метода:

import QtQuick 2.12

Item {
    function fibonacci(n){
        var arr = [0, 1];
        for (var i = 2; i < n + 1; i++)
            arr.push(arr[i - 2] + arr[i -1]);

        return arr;
    }
    TapHandler {
        onTapped: console.log(fibonacci(10))
    }
}

Функция fibonacci выполняется всякий раз, когда TapHandler генерирует сигнал tapped.

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

См. документацию Атрибуты объекта QML для получения дополнительной информации об определении пользовательских методов в QML с использованием JavaScript.

Функции, определённые в файле JavaScript

Нетривиальная логика программы лучше всего отделяется в отдельный файл JavaScript. Этот файл можно импортировать в QML с помощью инструкции import, подобно модулям QML .

Например, метод fibonacci() в предыдущем примере можно переместить во внешний файл с именем fib.js, и обратиться к нему так:

import QtQuick 2.12
import "fib.js" as MathFunctions

Item {
    TapHandler {
        onTapped: console.log(MathFunctions.fibonacci(10))
    }
}

Дополнительную информацию о загрузке внешних файлов JavaScript в QML см. в разделе Импортирование JavaScript-ресурсов в QML.

Подключение сигналов к JavaScript-функциям

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

Сигнал, отправленный объектом QML, может быть подключён к JavaScript-функции, вызвав метод connect() сигнала и передав JavaScript-функцию в качестве аргумента. Например, следующий код подключает сигнал tapped TapHandler к методу jsFunction() в script.js.

import QtQuick 2.12
import "script.js" as MyScript

Item {
    id: item
    width: 200; height: 200

    TapHandler {
        id: inputHandler
    }

    Component.onCompleted: {
        inputHandler.tapped.connect(MyScript.jsFunction)
    }
}
// script.js

function jsFunction() {
    console.log("Called JavaScript function!")
}

Функция jsFunction() вызывается всякий раз, когда генерируется сигнал tapped TapHandler.

См. Подключение сигналов к методам и сигналам для получения дополнительной информации.

JavaScript в коде запуска приложения

Иногда необходимо выполнить некоторый императивный код при запуске приложения (или экземпляра компонента). Хотя соблазнительно просто включить скрипт запуска как глобальный код во внешний файл скрипта, это может иметь серьёзные ограничения, так как среда QML может быть не полностью установлена. Например, некоторые объекты могут не быть созданы, или некоторые связи свойств могут не быть установлены. См. Ограничения среды выполнения JavaScript для точного определения ограничений кода глобальных скриптов.

Объект QML генерирует сигнал Component.completed attached при завершении создания экземпляра. JavaScript-код в соответствующем обработчике Component.onCompleted выполняется после создания объекта. Таким образом, лучшее место для написания кода запуска приложения — в обработчике Component.onCompleted объекта верхнего уровня, потому что этот объект генерирует Component.completed при полной установке среды QML.

Например:

import QtQuick 2.0

Rectangle {
    function startupFunction() {
        // ... startup code
    }

    Component.onCompleted: startupFunction();
}

Любой объект в файле QML — включая вложенные объекты и вложенные экземпляры компонентов QML — может использовать это присоединённое свойство. Если существует более одного обработчика onCompleted() для выполнения при запуске, они выполняются последовательно в неопределённом порядке.

Также каждый Component генерирует сигнал destruction() непосредственно перед уничтожением.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.0/qtqml-javascript-expressions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API