Evgenii Legotckoi
Evgenii Legotckoi11 жовтня 2018 р. 14:04

Qt/C++ - Підручник 084. Як запустити код JavaScript у програмі C++ на прикладі роботи з двома змінними

Допустимо, перед вами постало завдання щодо виконання 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 ( Вона також працюватиме).

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:50бали,
  • Рейтинг балів-4
m
  • molni99
  • 26 жовтня 2024 р. 01:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
m
  • molni99
  • 26 жовтня 2024 р. 01:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20бали,
  • Рейтинг балів-10
Останні коментарі
ИМ
Игорь Максимов22 листопада 2024 р. 11:51
Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 жовтня 2024 р. 14:37
Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 жовтня 2024 р. 08:19
Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов05 жовтня 2024 р. 07:51
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas505 липня 2024 р. 11:02
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi24 червня 2024 р. 15:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey115 листопада 2024 р. 06:04
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProject04 червня 2022 р. 03:49
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9Anonim25 жовтня 2024 р. 09:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Слідкуйте за нами в соціальних мережах