Класс QJSEngine
Класс QJSEngine предоставляет среду для оценки кода JavaScript. Подробнее...
| Заголовок: | #include <QJSEngine> |
| qmake: | QT += qml |
| С тех пор: | Qt 5.0 |
| Наследует: | QObject |
| Наследуется от: |
Этот класс был представлен в Qt 5.0.
Примечание: Все функции в этом классе являются реентерабельными.
Открытые типы
| перечисление | Extension { TranslationExtension, ConsoleExtension, GarbageCollectionExtension, AllExtensions } |
| флаги | Extensions |
Свойства
- uiLanguage : QString
Открытые функции
| QJSEngine(QObject *parent) | |
| QJSEngine() | |
| virtual | ~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()) |
| bool | isInterrupted() const |
| 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 | setInterrupted(bool interrupted) |
| void | setUiLanguage(const QString &language) |
| void | throwError(const QString &message) |
| void | throwError(QJSValue::ErrorType errorType, const QString &message = QString()) |
| QJSValue | toScriptValue(const T &value) |
| QString | uiLanguage() const |
Сигналы
| void | uiLanguageChanged() |
Связанные нечлены
| 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. Доступны следующие свойства:
namemessagefileNamelineNumberstack
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()). Аналогично, для создания объекта массива JavaScript используйте newArray().
Интеграция 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-объектов и функций.
Документация по типам членов
enum QJSEngine::Extensionflags 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 реализует подмножество 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.
Документация по свойству
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)
Вычисляет program, используя lineNumber в качестве базового номера строки, и возвращает результат вычисления.
Код сценария будет вычисляться в контексте глобального объекта.
Вычисление program может вызвать исключение в движке; в этом случае возвращаемое значение будет исключением, которое было возбуждено (обычно объект Error; см. QJSValue::isError()).
lineNumber используется для указания начального номера строки для program; информация о номере строки, предоставляемая движком в отношении этого вычисления, будет основана на этом аргументе. Например, если program состоит из двух строк кода, и оператор на второй строке вызывает исключение сценария, номер строки исключения будет lineNumber плюс один. Если начальный номер строки не указан, номера строк будут 1-основанными.
fileName используется для отчёта об ошибках. Например, в объектах ошибок имя файла доступно через свойство «fileName», если оно предоставлено этой функцией.
Примечание: Если было возбуждено исключение и значение исключения не является экземпляром Error (т.е. QJSValue::isError() возвращает false), значение исключения всё равно будет возвращено, но в настоящее время нет API для обнаружения того, что исключение произошло в этом случае.
template <typename T> 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-расширения для добавления функциональности, которая недоступна в стандартной реализации ECMAScript.
Расширения устанавливаются на заданный объект object или на глобальный объект, если объект не указан.
Несколько расширений можно установить одновременно, соединяя значения перечисления:
installExtensions(QJSEngine::TranslationExtension | QJSEngine::ConsoleExtension);
Эта функция была добавлена в Qt 5.6.
См. также Extension.
bool QJSEngine::isInterrupted() const
Возвращает значение, указывающее, прервана ли в данный момент выполнение JavaScript.
Эта функция была добавлена в Qt 5.14.
См. также setInterrupted().
QJSValue QJSEngine::newArray(uint length = 0)
Создаёт JavaScript-объект класса Array с заданной длиной length.
См. также newObject().
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().
QJSValue QJSEngine::newQMetaObject(const QMetaObject *metaObject)
Создаёт JavaScript-объект, оборачивающий данный QMetaObject. Объект metaObject должен существовать дольше, чем скриптовый движок. Рекомендуется использовать только эту функцию со статическими метаобъектами.
При вызове как конструктора будет создан новый экземпляр класса. Только конструкторы, экспонированные с помощью Q_INVOKABLE, будут видимы из скриптового движка.
Эта функция была добавлена в Qt 5.8.
См. также newQObject() и Интеграция QObject.
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().
void QJSEngine::setInterrupted(bool interrupted)
Прерывает или возобновляет выполнение JavaScript.
Если interrupted равно true, любое JavaScript, выполняемое этим движком, немедленно прерывается и возвращает объект ошибки, до тех пор, пока эта функция не будет снова вызвана со значением false для interrupted.
Эта функция потокобезопасна. Вы можете вызвать её из другого потока, чтобы, например, прервать бесконечный цикл в JavaScript.
Эта функция была добавлена в Qt 5.14.
См. также isInterrupted().
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().
template <typename T> QJSValue QJSEngine::toScriptValue(const T &value)
Создаёт QJSValue с заданным значением value.
См. также fromScriptValue().
Связанные нечлены
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.15/qjsengine.html