Spec-Zone.ru › Qt 5.13

Класс QJSEngine

Класс QJSEngine предоставляет среду для оценки JavaScript-кода. Подробнее...

Заголовок: #include <QJSEngine>
qmake: QT += qml
С тех пор: Qt 5.0
Наследует: QObject
Наследуется:

QQmlEngine

Этот класс был представлен в Qt 5.0.

  • Список всех членов, включая наследуемые
  • Устаревшие члены

Примечание: Все функции в этом классе являются реентерабельными.

Типы публичного доступа

Перечисление Extension { РасширениеПеревода, РасширениеКонсоли, РасширениеУборкиМусора, ВсеРасширения }
Флаги Расширения

Публичные функции

QJSEngine(QObject *parent)
QJSEngine()
виртуальный ~QJSEngine() override
void collectGarbage()
QJSValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1)
T fromScriptValue(const QJSValue &value)
QJSValue globalObject() const
QJSValue importModule(const QString &fileName)
void installExtensions(QJSEngine::Extensions extensions, const QJSValue &object = QJSValue())
QJSValue newArray(uint length = 0)
QJSValue newErrorObject(QJSValue::ErrorType errorType, const QString &message = QString())
QJSValue newObject()
QJSValue newQMetaObject(const QMetaObject *metaObject)
QJSValue newQMetaObject()
QJSValue newQObject(QObject *object)
void throwError(const QString &message)
void throwError(QJSValue::ErrorType errorType, const QString &message = QString())
QJSValue toScriptValue(const T &value)

Связанные нечлены

QJSEngine * qjsEngine(const QObject *object)

Подробное описание

Оценивание скриптов

Используйте evaluate() для оценки скрипт-кода.

QJSEngine myEngine;
QJSValue three = myEngine.evaluate("1 + 2");

evaluate() возвращает QJSValue, содержащую результат оценки. Класс QJSValue предоставляет функции для преобразования результата в различные типы C++ (например, QJSValue::toString() и QJSValue::toNumber()).

Следующий фрагмент кода демонстрирует, как можно определить функцию скрипта и затем вызвать её из C++ с помощью QJSValue::call():

QJSValue fun = myEngine.evaluate("(function(a, b) { return a + b; })");
QJSValueList args;
args << 1 << 2;
QJSValue threeAgain = fun.call(args);

Как видно из приведенных фрагментов, скрипт предоставляется движку в виде строки. Один из распространенных способов загрузки скриптов — это чтение содержимого файла и передача его в evaluate():

QString fileName = "helloworld.qs";
QFile scriptFile(fileName);
if (!scriptFile.open(QIODevice::ReadOnly))
    // handle error
QTextStream stream(&scriptFile);
QString contents = stream.readAll();
scriptFile.close();
myEngine.evaluate(contents, fileName);

Здесь мы передаем имя файла в качестве второго аргумента в evaluate(). Это никак не влияет на оценку; второй аргумент — это строка общего назначения, хранящаяся в объекте Error для целей отладки.

Для более крупных функциональных блоков вы можете упаковать свой код и данные в модули. Модуль — это файл, содержащий скрипт-код, переменные и т. д., а также использует инструкции export для описания своего интерфейса для остальной части приложения. С помощью import-инструкций модуль может ссылаться на функциональность из других модулей. Это позволяет безопасно создавать скриптовое приложение из более мелких взаимосвязанных блоков. В отличие от этого, подход с использованием evaluate() несёт риск, что внутренние переменные или функции одного вызова evaluate() случайно загрязнят глобальный объект и повлияют на последующие оценки.

Следующий пример предоставляет модуль, который может складывать числа:

export function sum(left, right)
{
    return left + right
}

Этот модуль можно загрузить с помощью QJSEngine::import(), если он сохранён под именем math.mjs:

QJSvalue module = myEngine.importModule("./math.mjs");
QJSValue sumFunction = module.property("sum");
QJSValue result = sumFunction.call(args);

Модули также могут использовать функциональность других модулей с помощью инструкций import:

import { sum } from "./math.mjs";
export function addTwice(left, right)
{
    return sum(left, right) * 2;
}

Настройка движка

Функция globalObject() возвращает связанный с движком скрипта Глобальный Объект. Свойства Глобального Объекта доступны из любого скрипт-кода (т. е. это глобальные переменные). Обычно, перед оценкой «пользовательских» скриптов, вы захотите настроить движок скриптов, добавив одну или несколько свойств к Глобальному Объекту:

myEngine.globalObject().setProperty("myNumber", 123);
...
QJSValue myNumberPlusOne = myEngine.evaluate("myNumber + 1");

Добавление пользовательских свойств в среду скриптирования является одним из стандартных способов предоставления скрипт-API, специфичного для вашего приложения. Обычно эти пользовательские свойства — объекты, созданные функциями newQObject() или newObject().

Исключения скрипта

evaluate() может генерировать исключение скрипта (например, из-за синтаксической ошибки). Если это произойдет, то evaluate() возвращает значение, которое было сгенерировано (обычно объект Error). Используйте QJSValue::isError() для проверки на наличие исключений.

Для получения подробной информации об ошибке используйте QJSValue::toString() для получения сообщения об ошибке и QJSValue::property() для запроса свойств объекта Error. Доступны следующие свойства:

  • name
  • message
  • fileName
  • lineNumber
  • stack
QJSValue result = myEngine.evaluate(...);
if (result.isError())
    qDebug()
            << "Uncaught exception at line"
            << result.property("lineNumber").toInt()
            << ":" << result.toString();

Создание объекта скрипта

Используйте newObject() для создания JavaScript-объекта; это аналог скрипт-выражения new Object(). Вы можете использовать функциональность объекта QJSValue для управления скрипт-объектом (например, QJSValue::setProperty()). Аналогично, используйте newArray() для создания JavaScript-массива.

Интеграция QObject

Используйте newQObject() для упаковки указателя на QObject (или подкласс). newQObject() возвращает прокси-объект скрипта; свойства, дочерние элементы, сигналы и слоты QObject доступны как свойства прокси-объекта. Код привязки не нужен, так как он выполняется динамически с помощью системы метаобъектов Qt.

QPushButton *button = new QPushButton;
QJSValue scriptButton = myEngine.newQObject(button);
myEngine.globalObject().setProperty("button", scriptButton);

myEngine.evaluate("button.checkable = true");

qDebug() << scriptButton.property("checkable").toBool();
scriptButton.property("show").call(); // call the show() slot

Используйте newQMetaObject() для упаковки QMetaObject; это даёт «скриптовое представление» класса на основе QObject. newQMetaObject() возвращает прокси-объект скрипта; значения перечислений класса доступны как свойства прокси-объекта.

Конструкторы, экспортированные в систему метаобъектов (с использованием Q_INVOKABLE), могут вызываться из скрипта для создания нового экземпляра QObject с JavaScriptOwnership. Например, приведённое ниже определение класса:

class MyObject : public QObject
{
    Q_OBJECT

public:
    Q_INVOKABLE MyObject() {}
};

staticMetaObject для класса можно экспортировать в JavaScript так:

QJSValue jsMetaObject = engine.newQMetaObject(&MyObject::staticMetaObject);
engine.globalObject().setProperty("MyObject", jsMetaObject);

Затем экземпляры класса можно создавать в JavaScript:

engine.evaluate("var myObject = new MyObject()");

Примечание: В настоящее время поддерживаются только классы, использующие макрос Q_OBJECT; невозможно экспортировать staticMetaObject класса Q_GADGET в JavaScript.

END_OF_DOCUMENT_MARKER ```

Динамические свойства QObject

Динамические свойства QObject не поддерживаются. Например, следующий код не будет работать:

QJSEngine engine;

QObject *myQObject = new QObject();
myQObject->setProperty("dynamicProperty", 3);

QJSValue myScriptQObject = engine.newQObject(myQObject);
engine.globalObject().setProperty("myObject", myScriptQObject);

qDebug() << engine.evaluate("myObject.dynamicProperty").toInt();

Расширения

QJSEngine предоставляет совместимую реализацию ECMAScript. По умолчанию такие полезные функции, как ведение логов, недоступны, но их можно установить с помощью функции installExtensions().

См. также QJSValue, Делаем приложения интерактивными с помощью JavaScript и Список объектов и функций JavaScript.

Документация по типам членов

перечисление QJSEngine::Extensionфлаги QJSEngine::Extensions

Это перечисление используется для указания расширений, которые нужно установить с помощью installExtensions().

Константа Значение Описание
QJSEngine::TranslationExtension 0x1 Указывает, что необходимо установить функции перевода (например, qsTr()).
QJSEngine::ConsoleExtension 0x2 Указывает, что необходимо установить функции консоли (например, console.log()).
QJSEngine::GarbageCollectionExtension 0x4 Указывает, что необходимо установить функции сборки мусора (например, gc()).
QJSEngine::AllExtensions 0xffffffff Указывает, что необходимо установить все расширения.

TranslationExtension

Связь между функциями перевода скриптов и функциями перевода C++ описывается в следующей таблице:

Функция скрипта Соответствующая функция C++
qsTr() QObject::tr()
QT_TR_NOOP() QT_TR_NOOP()
qsTranslate() QCoreApplication::translate()
QT_TRANSLATE_NOOP() QT_TRANSLATE_NOOP()
qsTrId() qtTrId()
QT_TRID_NOOP() QT_TRID_NOOP()

Этот флаг также добавляет функцию arg() к прототипу строки.

Дополнительную информацию можно найти в документации Международные настройки с Qt.

ConsoleExtension

Объект console реализует подмножество Console API, который предоставляет знакомые функции ведения журнала, такие как console.log().

Список добавленных функций:

  • console.assert()
  • console.debug()
  • console.exception()
  • console.info()
  • console.log() (эквивалентно console.debug())
  • console.error()
  • console.time()
  • console.timeEnd()
  • console.trace()
  • console.count()
  • console.warn()
  • print() (эквивалентно console.debug())

Дополнительную информацию можно найти в документации API консоли.

GarbageCollectionExtension

Функция gc() эквивалентна вызову collectGarbage().

Тип Extensions является псевдонимом для QFlags<Extension>. Он хранит логическое ИЛИ сочетание значений Extension.

Документация по функциям-членам

QJSEngine::QJSEngine(QObject *parent)

Конструирует объект QJSEngine с заданным parent.

Объект globalObject() инициализирован с свойствами, описанными в ECMA-262, раздел 15.1.

QJSEngine::QJSEngine()

Конструирует объект QJSEngine.

Объект globalObject() инициализирован с свойствами, описанными в ECMA-262, раздел 15.1.

[override virtual] QJSEngine::~QJSEngine()

Удаляет этот объект QJSEngine.

Мусор из постоянной кучи JS не собирается во время удаления QJSEngine. Если вам нужно освободить всю память, вручную вызовите collectGarbage непосредственно перед удалением QJSEngine.

void QJSEngine::collectGarbage()

Выполняет сборщик мусора.

Сборщик мусора попытается вернуть память, найдя и удалив объекты, которые больше недоступны в среде скрипта.

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

QJSValue QJSEngine::evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1)

Вычисляет program, используя lineNumber в качестве базового номера строки и возвращает результат вычисления.

Код скрипта будет вычисляться в контексте глобального объекта.

Вычисление program может вызвать исключение исключение в движке; в этом случае возвращаемое значение будет исключением, которое было выброшено (обычно объект Error; см. QJSValue::isError()).

lineNumber используется для указания начального номера строки для program; информация о номере строки, предоставляемая движком в связи с этим вычислением, будет основана на этом аргументе. Например, если program состоит из двух строк кода, и оператор на второй строке вызывает исключение скрипта, номер строки исключения будет lineNumber плюс один. Если начальный номер строки не указан, номера строк будут 1-основанными.

fileName используется для вывода сообщений об ошибках. Например, в объектах ошибок имя файла доступно через свойство «fileName», если оно было предоставлено с помощью этой функции.

Примечание: Если было выброшено исключение, и значение исключения не является экземпляром Error (т. е. QJSValue::isError() возвращает false), значение исключения всё равно будет возвращено, но в настоящее время нет API для определения того, что исключение произошло в этом случае.

T QJSEngine::fromScriptValue(const QJSValue &value)

Возвращает заданное value, преобразованное в тип шаблона T.

См. также toScriptValue().

QJSValue QJSEngine::globalObject() const

Возвращает глобальный объект этого движка.

По умолчанию глобальный объект содержит встроенные объекты, которые являются частью ECMA-262, такие как Math, Date и String. Кроме того, вы можете задать свойства глобального объекта, чтобы сделать ваши собственные расширения доступными для всего кода скрипта. Нелокальные переменные в коде скрипта будут созданы в качестве свойств глобального объекта, а также локальные переменные в глобальном коде.

QJSValue QJSEngine::importModule(const QString &fileName)

Импортирует модуль, расположенный по адресу fileName, и возвращает объект пространства имён модуля, который содержит все экспортированные переменные, константы и функции в качестве свойств.

Если этот модуль импортируется в движок впервые, файл загружается из указанного расположения в локальной файловой системе или системе ресурсов Qt и вычисляется как модуль ECMAScript. Файл ожидается в кодировке UTF-8.

Последующие импорты того же модуля вернут ранее импортированный экземпляр. Модули являются одиночными и остаются до уничтожения движка.

Указанное fileName внутренне будет нормализовано с помощью QFileInfo::canonicalFilePath(). Это означает, что несколько импортов одного и того же файла на диске с использованием различных относительных путей загрузят файл только один раз.

Примечание: Если во время загрузки модуля было выброшено исключение, возвращаемое значение будет исключением (обычно объект Error; см. QJSValue::isError()).

Эта функция была введена в Qt 5.12.

void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSValue &object = QJSValue())

Устанавливает расширения JavaScript extensions, чтобы добавить функциональность, которая недоступна в стандартной реализации ECMAScript.

Расширения устанавливаются в заданном object или в глобальном объекте Global Object, если объект не указан.

Несколько расширений могут быть установлены одновременно, объединяя значения перечисления:

installExtensions(QJSEngine::TranslationExtension | QJSEngine::ConsoleExtension);

Эта функция была введена в Qt 5.6.

См. также Extension.

QJSValue QJSEngine::newArray(uint length = 0)

Создаёт JavaScript-объект класса Array с заданной длиной.

См. также newObject().

QJSValue QJSEngine::newErrorObject(QJSValue::ErrorType errorType, const QString &message = QString())

Создаёт JavaScript-объект класса Error.

Прототипом созданного объекта будет errorType.

Эта функция была добавлена в Qt 5.12.

См. также newObject(), throwError() и QJSValue::isError().

QJSValue QJSEngine::newObject()

Создаёт JavaScript-объект класса Object.

Прототипом созданного объекта будет прототип объекта Object.

См. также newArray() и QJSValue::setProperty().

QJSValue QJSEngine::newQMetaObject(const QMetaObject *metaObject)

Создаёт JavaScript-объект, оборачивающий заданный QMetaObject. metaObject должен существовать дольше, чем движок сценария. Рекомендуется использовать этот метод только со статическими метаобъектами.

При вызове в качестве конструктора будет создан новый экземпляр класса. Только конструкторы, экспонированные с помощью Q_INVOKABLE, будут видны из движка сценария.

Эта функция была добавлена в Qt 5.8.

См. также newQObject() и Интеграция QObject.

QJSValue QJSEngine::newQMetaObject()

Создаёт JavaScript-объект, оборачивающий статический QMetaObject, связанный с классом T.

Эта функция была добавлена в Qt 5.8.

См. также newQObject() и Интеграция QObject.

QJSValue QJSEngine::newQObject(QObject *object)

Создаёт JavaScript-объект, оборачивающий заданный QObject object, используя JavaScriptOwnership.

Сигналы и слоты, свойства и дочерние элементы object доступны как свойства созданного QJSValue.

Если object — указатель на нулевой объект, эта функция возвращает нулевое значение.

Если для класса object (или его суперкласса рекурсивно) зарегистрирован прототип по умолчанию, прототип нового объекта сценария будет установлен на этот прототип по умолчанию.

Если заданный object удаляется вне управления движком, любая попытка доступа к удалённым членам QObject через объект-оболочку JavaScript (как из кода сценария, так и из C++) приведёт к исключению сценария.

См. также QJSValue::toQObject().

void QJSEngine::throwError(const QString &message)

Выбрасывает ошибку времени выполнения (исключение) с заданным сообщением message.

Этот метод является C++-аналогом выражения throw() в JavaScript. Он позволяет коду C++ сообщать об ошибках времени выполнения в QJSEngine. Поэтому его следует вызывать только из кода C++, вызванного функцией JavaScript через QJSEngine.

При возвращении из C++, движок прервёт нормальный поток выполнения и вызовет следующий предварительно зарегистрированный обработчик исключений с объектом ошибки, содержащим заданное сообщение message. Объект ошибки будет указывать на расположение самого верхнего контекста в стеке вызова JavaScript; конкретно, у него будут свойства lineNumber, fileName и stack. Эти свойства описаны в Исключения сценария.

В следующем примере C++-метод в FileAccess.cpp выбрасывает ошибку в qmlFile.qml в позиции, где вызывается readFileAsText():

// qmlFile.qml
function someFunction() {
  ...
  var text = FileAccess.readFileAsText("/path/to/file.txt");
}
// FileAccess.cpp
// Assuming that FileAccess is a QObject-derived class that has been
// registered as a singleton type and provides an invokable method
// readFileAsText()

QJSValue FileAccess::readFileAsText(const QString & filePath) {
  QFile file(filePath);

  if (!file.open(QIODevice::ReadOnly)) {
    jsEngine->throwError(file.errorString());
    return QString();
  }

  ...
  return content;
}

Также можно перехватить брошенную ошибку в JavaScript:

// qmlFile.qml
function someFunction() {
  ...
  var text;
  try {
    text = FileAccess.readFileAsText("/path/to/file.txt");
  } catch (error) {
    console.warn("In " + error.fileName + ":" + "error.lineNumber" +
                 ": " + error.message);
  }
}

Если вам нужна более специфическая ошибка времени выполнения для описания исключения, вы можете использовать перегрузку throwError(QJSValue::ErrorType errorType, const QString &message).

Эта функция была добавлена в Qt 5.12.

См. также Исключения сценария.

void QJSEngine::throwError(QJSValue::ErrorType errorType, const QString &message = QString())

Эта функция перегружает throwError().

Выбрасывает ошибку времени выполнения (исключение) с заданным errorType и message.

// Assuming that DataEntry is a QObject-derived class that has been
// registered as a singleton type and provides an invokable method
// setAge().

void DataEntry::setAge(int age) {
  if (age < 0 || age > 200) {
    jsEngine->throwError(QJSValue::RangeError,
                         "Age must be between 0 and 200");
  }
  ...
}

Эта функция была добавлена в Qt 5.12.

См. также Исключения сценария и newErrorObject().

QJSValue QJSEngine::toScriptValue(const T &value)

Создаёт QJSValue с заданным значением value.

См. также fromScriptValue().

Связанные внеклассные функции

QJSEngine *QJSEngine::qjsEngine(const QObject *object)

Возвращает QJSEngine, связанный с object, если таковой имеется.

Эта функция полезна, если вы экспонировали QObject в среду JavaScript, а затем в вашей программе хотите получить к нему доступ. Она не требует хранения оболочки, возвращаемой QJSEngine::newQObject().

Эта функция была добавлена в Qt 5.5.

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

Spec-Zone.ru

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