Класс QJSEngine
Класс QJSEngine предоставляет среду для оценки кода JavaScript. Подробнее...
| Заголовок: | #include <QJSEngine> |
| qmake: | QT += qml |
| С момента: | Qt 5.0 |
| Наследует: | QObject |
| Наследуется от: |
Примечание: Все функции в этом классе являются реентерабельными.
Типы публичного доступа
| перечисление | Extension { TranslationExtension, ConsoleExtension, GarbageCollectionExtension, AllExtensions } |
| флаги | Extensions |
Функции публичного доступа
| QJSEngine() | |
| QJSEngine(QObject *parent) | |
| виртуальный | ~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) |
- 31 функция публичного доступа, унаследованная от QObject
Статические члены публичного доступа
| const QMetaObject | staticMetaObject |
- 9 статических членов публичного доступа, унаследованных от QObject
Связанные внешние члены
| QJSEngine * | qjsEngine(const QObject *object) |
Дополнительные унаследованные члены
- 1 свойство, унаследованное от QObject
- 1 слот публичного доступа, унаследованный от QObject
- 2 сигнала, унаследованные от QObject
- 9 защищенных функций, унаследованных от QObject
Подробное описание
Класс QJSEngine предоставляет среду для оценки кода JavaScript.
Оценивание скриптов
Используйте 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. Доступны следующие свойства:
namemessagefileNamelineNumberstack
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; невозможно сделать доступным для JavaScript staticMetaObject класса Q_GADGET.
Динамические свойства 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()). |
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())
Дополнительную информацию см. в документации по Console API.
GarbageCollectionExtension
Функция gc() эквивалентна вызову collectGarbage().
Тип Extensions является псевдонимом для QFlags<Extension>. Он хранит логическое ИЛИ сочетание значений Extension.
Документация по функциям членов
QJSEngine::QJSEngine()
Создаёт объект QJSEngine.
Объект globalObject() инициализируется свойствами, описанными в ECMA-262, Раздел 15.1.
QJSEngine::QJSEngine(QObject *parent)
Создаёт объект QJSEngine с заданным parent.
Объект 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.
END_OF_DOCUMENT_MARKER ```void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSValue &object = QJSValue())
Устанавливает JavaScript-расширения для добавления функциональности, которая недоступна в стандартной реализации ECMAScript.
Расширения устанавливаются для данного объекта или для глобального объекта, если объект не указан.
Несколько расширений можно установить одновременно, перечислив значения перечисления:
OR Эта функция была добавлена в 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 равен null, эта функция возвращает null.
Если для класса object (или его суперкласса, рекурсивно) зарегистрирован прототип по умолчанию, прототип нового объекта сценария будет установлен на этот прототип по умолчанию.
Если данный object удалён вне управления движка, любая попытка получить доступ к членам удалённого QObject через JavaScript-объект-обёртку (либо кодом сценария, либо с C++) приведёт к исключению сценария.
См. также QJSValue::toQObject().
void QJSEngine::throwError(const QString &message)
Выбрасывает ошибку выполнения (исключение) с заданным сообщением.
Этот метод является C++ аналогом throw() выражения в JavaScript. Он позволяет коду C++ сообщать об ошибках выполнения в QJSEngine. Поэтому вызывать его следует только из кода C++, вызванного функцией JavaScript через QJSEngine.
При возвращении из C++, движок прервёт нормальный поток выполнения и вызовет следующий зарегистрированный обработчик исключений с объектом ошибки, содержащим данное сообщение. Объект ошибки укажет на местоположение самого верхнего контекста в стеке вызова 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 и сообщением.
// 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 с заданным значением.
См. также fromScriptValue().
Связанные нечлены
QJSEngine *qjsEngine(const QObject *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-5.12/qjsengine.html