Privacy policyContactsAbout siteOpinionsGitHubDonate
© EVILEG 2015-2018
Recommend hosting
TIMEWEB

Qt/C++ - Tutorial 084. How to run JavaScript code in a C ++ application using the example of working with two variables

Qt, QScriptEngine, QScriptValue, JavaScript, QScriptContext

Suppose you are faced with the task of executing JavaScript code in a C++ application. For example, there is a set of output data or variables whose names are known in advance, and there are pieces of JavaScript code that does something with these variables. And there is also an algorithm that, if there are any conditions, it will choose. which javascript code should be run.

Also, you can't just take and rewrite that JavaScript code into C++ code and hardcorely add it to the application. Since there are a lot of such pieces of code, at the same time other people are engaged in their maintenance and constantly add new pieces of code.

That is, in this case, the set of input data and JavaScript code for us is data, in some way the content that we launch using a certain algorithm, according to which we choose, under what conditions to choose one or another for the same set of input variables a piece of javascript code.

I hope that I clearly explained why we need to run the execution of JavaScript code in a C++ application.

I suggest to write an application that has two input fields for variable names, two input fields with input for the values of these variables in double format, in case of entering a value other than double data type, we will set the value to Undefined .

We will also add an TextEdit input field for writing JavaScript code that we will execute in our application.

And the last input field will be called Result (this will be TextEdit ), which will be responsible for the output of the new calculated values of the variables we entered.

Also add a QPushButton, which will run the execution of JavaScript code.

The application will look like the image below.

Project structure

We write a project with a minimal structure. In essence, the project has a structure that is created by default.

The only important difference from the default pro file will be that we need to connect the script module.

This is done in the JSCalculation.pro file.

QT       += core gui widgets script

Widget.ui

In this article I will not describe how I created the application form in Qt Designer, this is not so important to us, and it does not apply to the topic of the article. Just list the objects that will be used in the source code of the widget with the name of their class

  • nameLineEdit_1 - QLineEdit
  • nameLineEdit_2 - QLineEdit
  • valueLineEdit_1 - QLineEdit
  • valueLineEdit_2 - QLinEdit
  • execPushButton - QPushButton
  • javaScriptTextEdit - QPlainTextEdit
  • resultTextEdit - QPlainTextEdit

Now let's proceed directly to the implementation of our project.

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:
    // Everything is by default, except for this slot, which will execute JavaScript and count variables
    void onExecPushButtonClicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

Widget.cpp

And now the application code itself

#include "Widget.h"
#include "ui_Widget.h"

// We need the following classes
#include <QScriptEngine>
#include <QScriptContext>
#include <QScriptValue>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    // Connect signal from button to slot
    connect(ui->execPushButton, &QPushButton::clicked, this, &Widget::onExecPushButtonClicked);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::onExecPushButtonClicked()
{
    // Create a JavaScript engine object
    QScriptEngine engine;
    // Take from it the context in which we will work.
    // In this case, a new context is created.
    QScriptContext* context = engine.pushContext();

    // Take the names of the variables with which to work
    const QString var_1 = ui->nameLineEdit_1->text();
    const QString var_2 = ui->nameLineEdit_2->text();

    // Set the variables by trying to convert the text of the QLineEdit fields to double
    bool ok = false;

    double value = ui->valueLineEdit_1->text().toDouble(&ok);
    if (ok)
    {
        // Set variable with value as properties of the script activation object.
        context->activationObject().setProperty(var_1, value);
    }
    else
    {
        // If the conversion fails, the value will be Undefined.
        context->activationObject().setProperty(var_1, QScriptValue::UndefinedValue);
    }

    value = ui->valueLineEdit_2->text().toDouble(&ok);
    if (ok)
    {
         // Set variable with value as properties of the script activation object.
        context->activationObject().setProperty(var_2, value);
    }
    else
    {
        // If the conversion fails, the value will be Undefined.
        context->activationObject().setProperty(var_2, QScriptValue::UndefinedValue);
    }

    // Run the script
    engine.evaluate(ui->javaScripTextEdit->toPlainText());

    // We clear the field of output of the result from the previous values
    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());

    // Remove context
    engine.popContext();

    // Since the QScriptEngine is created on the method stack, it will be deleted automatically when the method ends.
}

Conclusion

You can first enter the names of the variables and their values to make sure that everything works fine without JavaScript code.

Also, the application should not fall and end with errors. If the JavaScript code that you will enter and as shown at the very beginning of the article does not give the result that you expect, then it is probably worth a close look at your JavaScript code, most likely you made a mistake. Also, QScriptEngine supports some standard JavaScript functionality, for example, the Math library (It will also work).


Comment

Comment

Only authorized users can write comments.
Sign in or Register, Please
Nov. 16, 2018, 7:09 p.m.
Илья Завьялов

Qt - Test 001. Signals and slots

  • Result:31points,
  • Rating scores-10
Nov. 16, 2018, 12:49 p.m.
Ирина Минигузина

C++ - Тест 003. Условия и циклы

  • Result:0points,
  • Rating scores-10
Nov. 16, 2018, 8:55 a.m.
Vitaliy

Qt - Test 001. Signals and slots

  • Result:52points,
  • Rating scores-4
Recent comments
Nov. 16, 2018, 6:50 a.m.
Евгений Легоцкой

Добрый день! шаблон не находит, или шаблон неправильно прописали, или тег шаблона неправильно написан, иных выводов сделать не могу, из того, что вы написали. трейсбек нужно смотреть. Со...
Nov. 16, 2018, 6:48 a.m.
Евгений Легоцкой

пройтись циклом по всем виджетам в обратном порядке for (int i = ui->vertialLayout->count() - 1; i >= 0; --i){ QWidget* w = ui->verticalLyout->itemAt(i)->widget();...
Nov. 15, 2018, 9:35 p.m.
chunk

Доброго времени суток Евгений. Не подскажете что я делаю не так? Получаю ошибку такого характера: Reverse for 'add_comment' with arguments '('',)' not found. 1 pattern(s) tried: ...
Nov. 15, 2018, 3:35 p.m.
Михаиллл

Спасибо. Похоже где то описку сделал, поэтому не работало. Я добавил на verticalLayout много виджитов. А можно ли их как то быстро и просто удалить?
Nov. 15, 2018, 2:55 p.m.
Евгений Легоцкой

verticalLayout - это, по-моему предположению, должен быть у вас объект класса QVBoxLayout, который наследован от QBoxLayout. Поэтому открываете документацию на QVBoxLayout ...
Now discuss on the forum
Nov. 17, 2018, 11:20 p.m.
Евгений Легоцкой

Три года назад я подключал ffmpeg в проект на Qt/С++ на первой работе. И кодирование декодирование удалось запустить. Подключал как библиотеку. Думаю, что в зависимости от проекта мо...
Nov. 17, 2018, 2:13 p.m.
Чарльз Грин

Я сейчас занимаюсь мультимедией, это аудио и видео, программы для концертов и т. д. Бибилиотека Qt очень помогает, она надежная, а надежность в моих приложениях очень важный фактор чтоб не пол...
Nov. 16, 2018, 4:28 p.m.
Евгений Легоцкой

Добрый день! Спасибо, что воспользовались именно форумом. Заниматься курсовыми работами чьими-то ни было у меня времени нет, у самого полторы работы. Но что-то подсказать на фо...
Nov. 16, 2018, 9:52 a.m.
Евгений Легоцкой

Отладчик!!!! Версия комплекта MSVC 2015 + компилятор 14.0!!!!
Join us in social networks

For registered users on the site there is a minimum amount of advertising