QtScript 模块起源于 QSA,在Qt4.6时,QtScript 进行过完全重写。原来的QtScript 以 Qt Script classic的名字放到了 Qt Solutions 中。
对 javascript 几乎一窍不通,主要学习一下 脚本代码 与 C++ 代码的整合。
#include <QtCore/QCoreApplication> #include <QtCore/QDebug> #include <QtScript> const char script[]="1+2"; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QScriptEngine engine; QScriptValue res = engine.evaluate(script); if (res.isError()) qDebug()<<"Error"; else qDebug()<<res.toNumber(); return a.exec(); }
当脚本执行出错时,返回一个Error对象,就像我们前面所做的,使用 isError 可判断。但若要获得更多的出错信息:
#include <QtCore/QCoreApplication> #include <QtCore/QDebug> #include <QtScript> const char script[]="1+a"; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QScriptEngine engine; QScriptValue res = engine.evaluate(script); if (engine.hasUncaughtException()){ qDebug()<<engine.uncaughtException().toString(); qDebug()<<engine.uncaughtExceptionBacktrace().join("/n"); }else{ qDebug()<<res.toNumber(); } return a.exec(); }
可以使用 hasUncaughtException 来进行判断。程序结果如下:
"ReferenceError: Can't find variable: a" "<anonymous>()@:1"
如果我们这儿的脚本是从hello.js文件的第3行读入的,我们可以传递额外的信息:
QScriptValue res = engine.evaluate(script, "hello.js", 3);
这样会得到更友好的信息:
"ReferenceError: Can't find variable: a" "<anonymous>()@hello.js:3"
这也是一个 QScriptValue,通过设置它的属性,可以在脚本中访问C++中的数据和对象
接前面的例子,在执行脚本前,添加一句:
engine.globalObject().setProperty("a", 797);
使得整数797在脚本中作为a被访问,这样错误即可消失。
#include <QtGui> #include <QtScript> const char script[]="(function() { print('hello script'); })"; int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton button("Click Me"); QScriptEngine engine; QScriptValue func = engine.evaluate(script); qScriptConnect(&button, SIGNAL(clicked()), engine.globalObject(), func); button.show(); return app.exec(); }
为了代码少点,此处有意省略了错误检查。在这是代码中是不可少的,不然可能都不知道自己怎么死的 :-)
注意:
const char script[]="f = function() { print('hello script'); }";
#include <QtCore> #include <QtGui> #include <QtScript> const char script[]="lineedit.setText('hello script')"; int main(int argc, char *argv[]) { QApplication app(argc, argv); QLineEdit lineEdit; QScriptEngine engine; QScriptValue edit = engine.newQObject(&lineEdit); engine.globalObject().setProperty("lineedit", edit); engine.evaluate(script); lineEdit.show(); return app.exec(); }
#include <QtCore> #include <QtGui> #include <QtScript> const char script[]="var obj = {fun:function(){print('hello script');}};" "btn.clicked.connect(obj, 'fun')"; int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton button("Click Me"); QScriptEngine engine; QScriptValue btn = engine.newQObject(&button); engine.globalObject().setProperty("btn", btn); engine.evaluate(script); button.show(); return app.exec(); }
上面的 btn.clicked.connect(obj, 'fun') 也可写为
btn.clicked.connect(obj.fun)
脚本中发射信号,直接调用信号函数即可。
const char script[]="var obj = {fun:function(){print('hello script');}}/n" "btn.clicked.connect(obj, 'fun')/n" "btn.clicked()";
信号必须在C++中定义,script中不能定义信号