QT provides good support for JavaScript, and if you look through the documentation, you know that QT has two different JS package engines:
Qscriptengine appears earlier (since Qt4.3), based on WebKit's JavaScriptCore engine, which provides relatively rich APIs, but has been officially labeled deprecated Qjsengine is the official version of the Qt5.0, based on Google's V8 engine, which is available from the start. As for why Qscriptengine will be discarded by QT, various reasons are more complicated, interested friends can see this link, I briefly summarize here about the QT JS Module implementation history and reasons:
- Qscriptengine---Use the self-built JS engine:
功能落后、运行非常慢
.
- Qscriptengine---Use the javascriptcore engine (WebKit's main engine):
- The JS API provided by this package
暴露了实现细节
.
- Because of the different ways of design usage
一些原有函数无法实现(例如QScriptContext)
.
- JavaScriptCore change is too large for
没有一个稳定的API
qtscript to achieve the desired function, each time the engine changes will need to qtscript module inside the big adjustment.
- Qscriptengine---Use V8 engine:
V8对外提供的API稳定
, 可嵌入
into the program, but V8 and javascriptcore internal details, some concepts of Qtscript API cannot be mapped naturally To V8, the old interface that uses V8 to achieve the same performance requires considerable input , but the QML team is unable to accept such input costs.
- Qjsengine-------Use the V8 engine.
1. Qscriptengine VS Qjsengine
From the two main engine classes, compared to Qscriptengine, although the qjsengine come out late, but the core function (bold) is also supported, only a few other small features (not bold):
- Executes the script string.
- Engine global variable configuration.
- Exception handling.
- JS Object creation
- Qt class and JS Interactive integration.
- JS extension.
- Custom C + + classes (non-QT built-in).
- C + + functions and JS interaction integration.
- long-running script optimization processing.
- Debug tracing.
But after all, the JavaScriptCore engine package is more mature, from the qscriptengine derived from the technical support is certainly relatively rich, the use is more convenient. For example, the Qtscript module contains QScriptClassPropertyIterator
classes to provide Java-style property traversal capabilities, QScriptContext
classes to provide contextual information, and so on. But with the release of the new QT version, Qjsengine is certainly getting more and more mature. It should be noted that both of these should not be used in interaction with Qt's Web module (the pro-test qjsengine and Qwebengineview interaction is not valid), after all, are divided into two different modules.
2. Qjsengine Introduction
Here we simply learn qjsengine, as always, we have a small example to learn the current JS engine provides the main functions, in fact, the use is very simple.
2.1 Execute Script
Qjsvalue qjsengine::evaluate (const QString &program, const QString &filename = QString (), int linenumber = 1)
We only need to pass the string containing the JS code to QJSEngine::evaluate()
This function, we can directly execute the JS code. The latter two parameters of the function are optional filenames and line numbers, which are included in the error message when the JS error occurs. In the sample program, when the user clicks the Execute button, we execute the user input JS code directly:
void MainWindow::on_buttonEvaluateJs_clicked(bool){ ui->lineEditJsResult->setText( m_jsEngine.evaluate(ui->lineEditEvaluateJs->text()).toString()); ui->lineEditJsResult->setEnabled(ui->buttonEvaluateJs->isEnabled());}
2.2 Configuring the engine's global variables (c++/js interaction)
Qjsvalue Qjsengine::globalobject () const
Qjsvalue Qjsengine::newobject ()
void Qjsvalue::setproperty (const QString &name, const qjsvalue &value)
Through the globalObject()
function we get the global variable of JS engine, this variable is a qjsvalue, is a qt to JS data type of a package , basically support all JS object operation. For example, we can determine if two qjsvalue are equal, are strictly equal, set properties, set prototypes, and so on. The global object is a JS variable that can be used directly in the JS code, and what we usually do is to set the properties of the global variable in the C + + code, and then use it directly in JS.
newObject()
function is used to create a new JS object, in the example we set 3 properties on the new JS object ( setProperty()
) for the user input of the left operand, right operand and operator, and then set this object as a property of the global object, and then we call these 3 properties in the JS code directly to calculate:
void MainWindow::on_buttonEvaluatePropertyCalculateResult_clicked(bool){ auto jsObject = m_jsEngine.newObject(); jsObject.setProperty("leftOperand", ui->lineEditPropertyLeft->text()); jsObject.setProperty("rightOperand", ui->lineEditPropertyRight->text()); m_jsEngine.globalObject().setProperty("cppObject", jsObject); ui->lineEditEvaluatePropertyResult->setText(m_jsEngine.evaluate( "cppObject.leftOperand" + ui->lineEditPropertyOperator->text() + "cppObject.rightOperand").toString()); ui->lineEditEvaluatePropertyResult->setEnabled( ui->buttonEvaluatePropertyCalculateResult->isEnabled());}
2.3 Qt/js Interactive (scripted)
Qjsvalue Newqobject (Qobject *object)
Signals and slots, properties and children of object are available as properties of the created Qjsvalue.
With newQObject()
This function, we can encapsulate the QT class as a JS object and integrate it into the JS engine. QT class signal slots , attributes and sub-objects can be used in JS through attributes, QT provides a strong local function support, JS provides a flexible way to use, think it is very excited. We can use this to manipulate the exported Qt object in JS, to change the appearance of the interface, to realize the scripting of the program function.
In the example we export a qpushbutton of streets and set it as a property of the JS engine global object:
m_jsEngine.globalObject().setProperty("cppButton", m_jsEngine.newQObject(ui->buttonChangeInJs));
When the user clicks on this button, we read the local JS file into Qstring and execute the code, and the JS code calls the setStyleSheet()
function (note that this is a slot) to change the appearance style of the button:
void mainwindow::on_buttonchangeinjs_clicked (bool) {QFile jsfile (":/js/demo.js"); if (Jsfile.open (qiodevice::readonly | Qiodevice::text)) {Auto Jsstr = qstring::fromstdstring (Jsfile.readall (). tostdstring ()); Auto Jsresult = m_jsengine.evaluate (JSSTR); if (Jsresult.iserror ()) Ui->buttonchangeinjs->settext (jsresult.tostring ()); }}function func () {cppbutton.setstylesheet (' Qpushbutton {background-color:qlineargradient ( x0:0, y0:0, X1:1, Y1:1, stop:0.0 #111111, stop:0.2 #222222, stop:0.4 #444444, stop:0.6 #888888, stop:0. 8 #aaaaaa, stop:1.0 #ffffff); Color:white;} Qpushbutton:hover {border:2px solid blue; Padding:1ex; } qpushbutton:pressed {background-color:qlineargradient ( x0:0, y0:0, X1:1, Y1:1, stop:0.0 #ff1111, stop:0.2 #22ff22, stop:0.4 #4444ff, stop:0.6 #88ee88, stop:0.8 #aaeeaa, stop:1.0 #ffffff); } ') Cppbutton.text = ' Changed in JS '}func ()
3. Running Results
The complete code is shown in the link.
Qt---javascript/qt Interactive, scripted