Возникла потребность в интерпретаторе простых функций в среде Qt. Например, у вас программа, где пользователь может сам ввести свою функцию, которая что-то считает (например, sin(x)). Как быть? В Qt есть хороший встроенный язык QtScript как раз для этих нужд. Единственно, что синтаксис у него под javascript, хотя мне больше по душе был бы C++, но ладно.
Внимание! В статье рассказываются аналогичные вещи про QJSEngine — заменитель QtScript.
При написании статьи и изучении материла использовался материал статьи Cистема плагинов Qt, построение графиков и Qt Script.
Мы будем рассматривать простые математические пользовательские функции с одной и двумя переменными. По аналогии с ними вы сможете модифицировать код под себя.
Постановка задачи: У нас в переменной типа QString записан код пользовательской функции: . Надо посчитать значение функции в этой точке.
Для объяснения буду использовать простое приложение в Qt на Qt Widgets. Как его создать описано в статье Базовое приложение в Qt Widgets (Qt GuiApplication).
Процесс
- Вначале нужно прописать в файле проекта .pro факт подключения QtScript через добавления слова script. Без этого не будут подключаться заголовочные файлы.
- В файле mainwindow.cpp или в том, что вам нужно пропишите подключение библиотеки:
- А в кнопке пропишите такой код:
- При запуске приложения и нажатии на кнопку получите вот это:
- Для функции с двумя аргументами (например,
) код будет немного отличаться:
- При запуске получим вот это:
1 |
QT += core gui script |
1 |
#include <QtScript/QScriptEngine> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//Подготовка double x=2;//в какой точки ищем значение функции QString CodeFunction="RESULT = Math.sin(x);RESULT = RESULT + 1;"; //Необходимые переменные double Result; QScriptEngine engine; QScriptValue scriptFun; //подготовка движка QtScript engine.evaluate("function fun(x)\n {\n var RESULT=0;\n"+CodeFunction+"\n return RESULT;\n}\n"); scriptFun = engine.globalObject().property("fun"); //Вычисление значения функции в точке Result = scriptFun.call(QScriptValue(), QScriptValueList() << x).toNumber(); ui->textEdit->insertPlainText(QString::number(Result)+"\n"); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//Подготовка double x=2, y=3;//в какой точки ищем значение функции QString CodeFunction="RESULT = x+y;"; //Необходимые переменные double Result; QScriptEngine engine; QScriptValue scriptFun; //подготовка движка QtScript engine.evaluate("function fun(x,y)\n {\n var RESULT=0;\n"+CodeFunction+"\n return RESULT;\n}\n"); scriptFun = engine.globalObject().property("fun"); //Вычисление значения функции в точке Result = scriptFun.call(QScriptValue(), QScriptValueList() << x << y).toNumber(); ui->textEdit->insertPlainText(QString::number(Result)+"\n"); |
Вычисление простого выражения
Если же вам нужно вычислить значение простого выражения без всяких переменных, то всё гораздо проще. Например, вы хотите вычислить пример . Тогда код будет выглядеть так:
1 2 3 4 5 6 7 |
QString CodeFunction="2+2*2"; QScriptEngine engine; double Result = engine.evaluate(CodeFunction).toNumber(); ui->textEdit->insertPlainText(QString::number(Result)+"\n"); |
Вот и всё пока) Вы можете спокойно вводить тексты функций на языке QtScript (для простых вычислений как javascript) через файлы, поля ввода и использовать как функции в своих вычислениях. Конечно, работа таких функций будет поменьше, чем у обычных, прописанных на С++ внутри программы, но это и естественно.