Spec-Zone.ru › Qt 6.0

Класс QJSEngine

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

Заголовок: #include <QJSEngine>
CMake: find_package(Qt6 COMPONENTS Qml REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Qml)
qmake: QT += qml
С момента: Qt 5.0
Наследует: QObject
Наследуется от:

QQmlEngine

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

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

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

Перечисление Extension { TranslationExtension, ConsoleExtension, GarbageCollectionExtension, AllExtensions }
Флаги Extensions
Перечисление ObjectOwnership { CppOwnership, JavaScriptOwnership }

Свойства

  • uiLanguage : QString

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

QJSEngine(QObject *parent)
QJSEngine()
virtual ~QJSEngine() override
void collectGarbage()
QJSValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1, QStringList *exceptionStackTrace = nullptr)
T fromScriptValue(const QJSValue &value)
QJSValue globalObject() const
QJSValue importModule(const QString &fileName)
void installExtensions(QJSEngine::Extensions extensions, const QJSValue &object = QJSValue())
bool isInterrupted() const
QJSValue newArray(uint length = 0)
QJSValue newErrorObject(QJSValue::ErrorType errorType, const QString &message = QString())
QJSValue newObject()

Сигналы

void uiLanguageChanged()

Статические публичные члены

QJSEngine::ObjectOwnership objectOwnership(QObject *object)
void setObjectOwnership(QObject *object, QJSEngine::ObjectOwnership ownership)

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

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() несёт риск того, что внутренние переменные или функции одного вызова 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() на C++. Вы можете использовать функции объекта 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.

Динамические свойства 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.

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

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

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

Константа Значение Описание
QJSEngine::TranslationExtension 0x1 Указывает на то, что следует установить функции перевода (например, qsTr()). Это также устанавливает свойство Qt.uiLanguage.
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 реализует подмножество 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::ObjectOwnership

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

Константа Значение Описание
QJSEngine::CppOwnership 0 Объект принадлежит коду C++ и менеджер памяти JavaScript никогда не удалит его. Метод destroy() JavaScript не может использоваться с этими объектами. Этот параметр аналогичен QScriptEngine::QtOwnership.
QJSEngine::JavaScriptOwnership 1 Объект принадлежит JavaScript. Когда объект возвращается в менеджер памяти JavaScript как возвращаемое значение вызова метода, менеджер памяти JavaScript отслеживает его и удаляет, если не осталось ссылок JavaScript и у него нет родительского объекта QObject::parent(). Объект, отслеживаемый одним QJSEngine, будет удалён во время деструктора этого QJSEngine. Таким образом, ссылки JavaScript между объектами с JavaScriptOwnership из двух разных движков не будут действительными, если один из этих движков будет удалён. Этот параметр аналогичен QScriptEngine::ScriptOwnership.

Как правило, приложению не нужно явно устанавливать собственность объекта. Менеджер памяти JavaScript использует эвристику для установки значения по умолчанию. По умолчанию объект, созданный менеджером памяти JavaScript, имеет JavaScriptOwnership. Исключение составляют корневые объекты, созданные с помощью вызовов QQmlComponent::create() или QQmlComponent::beginCreate(), которые по умолчанию имеют CppOwnership. Владение этими корневыми объектами считается переданным вызывающей стороне C++.

Объекты, не созданные менеджером памяти JavaScript, по умолчанию имеют CppOwnership. Исключение составляют объекты, возвращаемые вызовами методов C++; их собственность будет установлена в JavaScriptOwnership. Это относится только к явным вызовам методов или слотов Q_INVOKABLE, но не к вызовам свойств-получателей.

Вызов setObjectOwnership() переопределяет значение по умолчанию.

Документация свойств

[since 5.15] uiLanguage : QString

Это свойство содержит язык, используемый для перевода строк пользовательского интерфейса

Это свойство содержит имя языка, используемого для перевода строк пользовательского интерфейса. Оно экспонируется для чтения и записи как Qt.uiLanguage при установке QJSEngine::TranslationExtension в движке. Оно всегда экспонируется в экземплярах QQmlEngine.

Вы можете свободно устанавливать значение и использовать его в привязках. Рекомендуется устанавливать его после установки переводчиков в приложении. По соглашению, пустая строка означает, что перевод из языка исходного кода не должен выполняться.

Это свойство было добавлено в Qt 5.15.

Функции доступа:

QString uiLanguage() const
void setUiLanguage(const QString &language)

Сигнал уведомления:

void uiLanguageChanged()

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

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, QStringList *exceptionStackTrace = nullptr)

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

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

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

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

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

exceptionStackTrace используется для отчётности об неуловленных исключениях. Если вы передадите в него не нулевой указатель на QStringList, он заполнит его списком "сообщений о кадрах стека", если сценарий вызвал необработанное исключение, или пустым списком в противном случае. Сообщение о кадре стека имеет формат имя_функции:номер_строки:столбец:имя_файла

Примечание: В некоторых случаях, например, для нативных функций, имя функции и имя файла могут быть пустыми, а номер строки и столбец — -1.

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

template <typename T> T QJSEngine::fromScriptValue(const QJSValue &value)

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

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

QJSValue QJSEngine::globalObject() const

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

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

[since 5.12] QJSValue QJSEngine::importModule(const QString &fileName)

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

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

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

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

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

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

[since 5.6] void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSValue &object = QJSValue())

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

Расширения устанавливаются на заданный object или на Глобальный объект, если объект не указан.

Несколько расширений можно установить одновременно, используя конкатенацию значений перечисления:

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

Функция была добавлена в Qt 5.6.

См. также Extension.

[since 5.14] bool QJSEngine::isInterrupted() const

Возвращает значение, показывающее, прервано ли выполнение JavaScript в настоящий момент.

Функция была добавлена в Qt 5.14.

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

QJSValue QJSEngine::newArray(uint length = 0)

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

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

[since 5.12] QJSValue QJSEngine::newErrorObject(QJSValue::ErrorType errorType, const QString &message = QString())

Создаёт JavaScript-объект класса Error с message в качестве сообщения об ошибке.

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

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

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

QJSValue QJSEngine::newObject()

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

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

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

[since 5.8] QJSValue QJSEngine::newQMetaObject(const QMetaObject *metaObject)

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

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

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

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

[since 5.8] template <typename T> QJSValue QJSEngine::newQMetaObject()

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

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

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

QJSValue QJSEngine::newQObject(QObject *object)

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

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

Если object равен null, эта функция возвращает null.

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

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

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

[static] QJSEngine::ObjectOwnership QJSEngine::objectOwnership(QObject *object)

Возвращает владение object.

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

[since 5.14] void QJSEngine::setInterrupted(bool interrupted)

Прерывает или повторно разрешает выполнение JavaScript.

Если interrupted равно true, любое выполняемое этим движком JavaScript немедленно прерывается и возвращает объект ошибки до тех пор, пока эта функция не будет вызвана снова со значением false для interrupted.

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

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

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

[static] void QJSEngine::setObjectOwnership(QObject *object, QJSEngine::ObjectOwnership ownership)

Устанавливает ownership для object.

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

[since Qt 5.12] void QJSEngine::throwError(const QString &message)

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

Этот метод является аналогом выражения 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.

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

[since 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().

template <typename T> QJSValue QJSEngine::toScriptValue(const T &value)

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

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

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

[since 5.5] QJSEngine *qjsEngine(const QObject *object)

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

Эта функция полезна, если вы экспортировали 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-6.0/qjsengine.html

Spec-Zone.ru

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