https://habr.com/ru/post/481142/Данный пример построен на примере из книги 
М.Шлее «Qt профессиональное программирование на Qt» «Черепашья графика». Для лучшего понимания работы советую почитать раздел «Язык сценариев Qt Scripts».
В примере будет реализован простой терминал, в который можно вводить команды. Результат выполнения команд будет отображаться в этом же терминале. Пользовательский интерфейс будет реализован на QML. 
Создадим проект Qt Quick 
 Опишем форму. Файл main.qml:
Опишем форму. Файл main.qml: 
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
Window {
    id: window
    visible: true
    width: Screen.width/2
    height: Screen.height/2
    title: qsTr("Тест jsEnjine")
    property string consoleFontFamily: "Consolas"
    property int fontPixelSize: 14
    TextArea {
        id: textAreaLog
        anchors.bottom: rectangle.top
        anchors.bottomMargin: 3
        anchors.right: parent.right
        anchors.rightMargin: 3
        anchors.left: parent.left
        anchors.leftMargin: 3
        anchors.top: parent.top
        anchors.topMargin: 3
        readOnly: true
    }
    Rectangle {
        id: rectangle
        height: 25
        anchors.right: parent.right
        anchors.rightMargin: 3
        anchors.left: parent.left
        anchors.leftMargin: 3
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 3
        border.color: "#0c0a0a"
        TextEdit {
            id: textEditInput
            anchors.right: parent.right
            anchors.rightMargin: 5
            anchors.left: parent.left
            anchors.leftMargin: 5
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 5
            anchors.top: parent.top
            anchors.topMargin: 5
            font.pixelSize: fontPixelSize
        }
    }
}
Форма
 
Добавим в проект классы 
AppCore  и 
Console, немного допишем 
main.c
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "appcore.h"
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    AppCore appCore;
    QQmlApplicationEngine engine;
    QQmlContext *context = engine.rootContext();//Создаем корневой контекст
    //Загружаем объект в контекст для установки соединения, а 
    //так же определяем имя
    //по которому будет происходить соединение
    context->setContextProperty("appCore",&appCore);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if(engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}
appcore.h
#ifndef APPCORE_H
#define APPCORE_H
#include <QObject>
#include <QJSEngine>
#include "console.h"
class AppCore : public QObject
{
    Q_OBJECT
public:
    explicit AppCore(QObject *parent = nullptr);
private:
    QJSEngine   appScriptEngine;
    Console     *userConsole;
signals:
    Q_INVOKABLE void appEndTextArea(const QString& text);
    Q_INVOKABLE void clearTextArea();
public slots:
    Q_INVOKABLE void slotEvaluate(const QString& code);
};
#endif // APPCORE_H
appcore.c
#include "appcore.h"
AppCore::AppCore(QObject *parent) : QObject(parent)
{
    userConsole = new Console(this);
    QJSValue val = appScriptEngine.newQObject(userConsole);
    appScriptEngine.globalObject().setProperty("console",val);
    connect(userConsole, SIGNAL(appEndTextArea(QString)),this,SIGNAL(appEndTextArea(QString)));
    connect(userConsole, SIGNAL(clearTextArea()),this,SIGNAL(clearTextArea()));
}
void AppCore::slotEvaluate(const QString& code)
{
    QJSValue result = appScriptEngine.evaluate(code);
    if(result.isError()){
        QString er = QString("Ошибка в строке %1: %2").arg(result.property("lineNumber").toInt()).arg(result.toString());
        emit appEndTextArea(er);
    }
}
console.h
#ifndef CONSOLE_H
#define CONSOLE_H
#include <QObject>
class Console : public QObject
{
    Q_OBJECT
public:
    explicit Console(QObject *parent = nullptr);
    Q_INVOKABLE void log(const QString& message);
    Q_INVOKABLE void clear();
signals:
    Q_INVOKABLE void appEndTextArea(const QString& text);
    Q_INVOKABLE void clearTextArea();
};
#endif // CONSOLE_H
console.cpp
#include "console.h"
Console::Console(QObject *parent) : QObject(parent)
{
}
void Console::log(const QString& message)
{
    emit appEndTextArea(message);
}
void Console::clear()
{
    emit clearTextArea();
}
В конструкторе класса 
AppCore мы добавили экземпляр класса 
Console в 
QJSEngine, так же мы определили что будем обращаться к методам этого класса через 
«console»
QJSValue val = appScriptEngine.newQObject(userConsole);
appScriptEngine.globalObject().setProperty("console",val);
Сигнал 
appEndTextArea(const QString& text) — добавление текста в 
textAreaLog в 
main.qml.
Сигнал 
clearTextArea() — очистить область вывода текста 
textAreaLog в 
main.qml.
Слот 
slotEvaluate(const QString& code) — выполнение js кода, введенного в 
textEditInput в 
main.qml.
Допишем в 
main.qml обработчики сигналов:
Connections{
        target: appCore
        onAppEndTextArea:{
            textAreaLog.cursorPosition = textAreaLog.length;
            textAreaLog.append(text);
        }
        onClearTextArea:{
            textAreaLog.cursorPosition=0;
            textAreaLog.text = "";
        }
    }
Так же допишем в 
textEditInput сигнал, вызова слота 
void slotEvaluate(const QString& code):
TextEdit {
            id: textEditInput
            anchors.right: parent.right
            anchors.rightMargin: 5
            anchors.left: parent.left
            anchors.leftMargin: 5
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 5
            anchors.top: parent.top
            anchors.topMargin: 5
            font.pixelSize: fontPixelSize
            Keys.onReturnPressed:{
                if(textEditInput.text == "")return;
                appCore.slotEvaluate(text)
                clear()
            }
            Keys.onEscapePressed: clear()
        }
Теперь при вводе команды в 
textEditInput и нажатии 
Enter команда будет передана в 
slotEvaluate в 
AppCore. При нажатии ESC поле 
textEditInput очистится.
При запуске приложения, если мы введем в 
textEditInput команду console.log(«Hello world»), то в поле 
textAreaLog увидим Hello world. Если ввести команду неизвестную 
QJSEngine, то в терминале высветится ошибка.
 Таким образом,
Таким образом, мы написали приложение, в котором мы можем вызывать методы подключенных к QJSEngine классов и выводить результаты выполнения этих методов. Кто то скажет 
«А при чем тут JS? Ведь классы написаны на С++?», но это уже другая история…
Ссылка проекта на github