- 1. Структура проекту
- 2. Widget.ui
- 3. Widget.h
- 4. Widget.cpp
- 5. Висновок
Допустимо, перед вами постало завдання щодо виконання JavaScript коду в C++ додатку. Наприклад є набір вихідних даних або змінних, назви яких заздалегідь відомі, а також є шматки JavaScript коду, який щось робить з цими змінними. Причому ще є алгоритм, який за наявності будь-яких умов вибиратиме. який саме JavaScript код слід запускати.
Також, ви не можете просто взяти і переписати той JavaScript код на C++ код і хардкорно додати його до програми. Оскільки таких шматків коду дуже багато, їх обслуговуванням займаються інші люди і постійно додають нові шматочки коду.
Тобто в даному випадку набір вхідних даних і JavaScript код для нас є даними, певною мірою контентом, який ми запускаємо в роботу за допомогою певного алгоритму, за яким вибираємо, за яких умов для одного і того ж набору вхідних змінних вибирати той чи інший шматок JavaScript коду.
Сподіваюся, що я пояснив, чому нам потрібно запускати виконання JavaScript коду в C++ додатку.
Пропоную написати програму, яка має два поля введення імен змінних, два поля введення з введенням значень цих змінних у форматі double, у разі введення значення, відмінного від типу даних double , будемо встановлювати значення змінної Undefined .
Також додамо поле введення TextEdit для написання JavaScript коду, який ми будемо виконувати у нашому додатку.
І останнє поле введення буде називатися Result (це буде TextEdit), яке відповідатиме за виведення нових обчислених значень введених нами змінних.
Також додамо QPushButton, який запускатиме виконання JavaScript коду.
Програма буде виглядати так, як на малюнку нижче.
Структура проекту
Напишемо проект із мінімальною структурою. По суті, проект має структуру, яка створюється за замовчуванням.
Єдина важлива відмінність від дефолтного pro-файлу буде в тому, що нам потрібно підключити script модуль.
Це робиться у JSCalculation.pro файлі.
QT += core gui widgets script
Widget.ui
У цій статті я не описуватиму, як створював форму програми у Qt Designer, це нам не так важливо, та й до теми статті не відноситься. Лише перерахую ті об'єкти, які будуть використовуватися у вихідних кодах віджету з найменуванням їх класом
- nameLineEdit_1 - QLineEdit
- nameLineEdit_2 - QLineEdit
- valueLineEdit_1 - QLineEdit
- valueLineEdit_2 - QLinEdit
- execPushButton - QPushButton
- javaScriptTextEdit - QPlainTextEdit
- resultTextEdit - QPlainTextEdit
А тепер приступимо безпосередньо до реалізації нашого проекту
Widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget(); private slots: // Всё по умолчанию, кроме этого слота, который выполнит JavaScript и посчитает переменные void onExecPushButtonClicked(); private: Ui::Widget *ui; }; #endif // WIDGET_H
Widget.cpp
А тепер сам програмний код програми
#include "Widget.h" #include "ui_Widget.h" // Нам понадобяться следующие классы #include <QScriptEngine> #include <QScriptContext> #include <QScriptValue> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); connect(ui->execPushButton, &QPushButton::clicked, this, &Widget::onExecPushButtonClicked); } Widget::~Widget() { delete ui; } void Widget::onExecPushButtonClicked() { // Создадим объект движка JavaScript QScriptEngine engine; // Возьмём из него контекст, в котором будем работать // В данном случае создаётся новый контекст QScriptContext* context = engine.pushContext(); // Возьмём имена переменных, с которыми должны работать const QString var_1 = ui->nameLineEdit_1->text(); const QString var_2 = ui->nameLineEdit_2->text(); // Установим переменные, попытавшись сконвертировать текст QLineEdit полей в double bool ok = false; double value = ui->valueLineEdit_1->text().toDouble(&ok); if (ok) { // Устанавливаем переменные со значением в качестве свойств объекта активации скрипта context->activationObject().setProperty(var_1, value); } else { // Если конвертация не удалась, то значение будет Undefined context->activationObject().setProperty(var_1, QScriptValue::UndefinedValue); } value = ui->valueLineEdit_2->text().toDouble(&ok); if (ok) { // Устанавливаем переменные со значением в качестве свойств объекта активации скрипта context->activationObject().setProperty(var_2, value); } else { // Если конвертация не удалась, то значение будет Undefined context->activationObject().setProperty(var_2, QScriptValue::UndefinedValue); } // Запускаем выполнение скрипта engine.evaluate(ui->javaScripTextEdit->toPlainText()); // Очищаем поле вывада результата от предыдущих значений ui->resultTextEdit->clear(); // Выводим текущее состояние переменных ui->resultTextEdit->appendPlainText(var_1 + " = " + context->activationObject().property(var_1).toString()); ui->resultTextEdit->appendPlainText(var_2 + " = " + context->activationObject().property(var_2).toString()); // Удаляем контекст engine.popContext(); // Поскольку QScriptEngine создан на стеке метода, то он удалится автоматически по завершении метода }
Висновок
Можете спочатку ввести назви змінних та їх значення, щоб переконатися, що все працює і без JavaScript коду.
Також програма не повинна падати та завершуватися з помилками. Якщо JavaScript код, який ви будете вводити і як показано на початку статті, дає не той результат, який ви очікуєте, то можливо варто уважно подивитися на ваш JavaScript код, швидше за все ви припустилися помилки. Також QScriptEngine підтримує деякий стандартний функціонал JavaScript, наприклад бібліотеку Math ( Вона також працюватиме).