QtScript

QtScript 模块起源于 QSA,在Qt4.6时,QtScript 进行过完全重写。原来的QtScript 以 Qt Script classic的名字放到了 Qt Solutions 中。

对 javascript 几乎一窍不通,主要学习一下 脚本代码 与 C++ 代码的整合。

练习一

  • 为简单起见,假定所有的script文件都已被读入到一个字符串中
  • 创建一个 QScriptEngine 的实例
  • 执行 script脚本
  • 脚本结果存放在 QScriptValue 中

 

#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"

globalobject()

这也是一个 QScriptValue,通过设置它的属性,可以在脚本中访问C++中的数据和对象

接前面的例子,在执行脚本前,添加一句:

engine.globalObject().setProperty("a", 797);

使得整数797在脚本中作为a被访问,这样错误即可消失。

练习二

  • 在C++ 中通过信号槽使用 script 中的函数
  • 效果:点击按钮,调用 script 中的函数。

 

#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();
}
  • 信号槽的连接,使用 qScriptConnect 函数,大致和QObject::connect用法差不多。只不过后两个参数都是 QScriptValue 对象了。
  • 为了代码少点,此处有意省略了错误检查。在这是代码中是不可少的,不然可能都不知道自己怎么死的 :-)

注意:

  • 我们的脚本被一对圆括号扩住了,而这在Qt4.5及以前是不需要的,因为Qt4.6采用 javascriptcore核心改写,故采用了和 javascript 的eval一致的用法。
  • 或者,不使用匿名函数

 

const char script[]="f = function() { print('hello script'); }";

练习三

  • 使我们的QObject子类的对象在脚本中能够被访问

 

#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();
}
  • 通过 QScriptEngine 的 newQObject 为对象创建一个包装器(一个QScriptValue)
  • 将该包装器设置为 globalObject 的属性,使得对象能以 lineedit 名字在脚本中被访问

练习四

  • 在脚本中连接信号与槽

 

#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中不能定义信号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Command line: -prefix /home/liuyh/workspace/qt5.14.2-arm -opensource -confirm-license -release -strip -shared -xplatform linux-arm-gnueabi-g++ -optimized-qmake -c++std c++11 --rpath=no -pch -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcanvas3d -skip qtconnectivity -skip qtdatavis3d -skip qtdoc -skip qtgamepad -skip qtlocation -skip qtmacextras -skip qtnetworkauth -skip qtpurchasing -skip qtremoteobjects -skip qtscript -skip qtscxml -skip qtsensors -skip qtspeech -skip qtsvg -skip qttools -skip qttranslations -skip qtwayland -skip qtwebengine -skip qtwebview -skip qtwinextras -skip qtx11extras -skip qtxmlpatterns -make libs -make examples -nomake tools -nomake tests -gui -widgets -dbus-runtime --glib=no --iconv=no --pcre=qt --zlib=qt -no-openssl --freetype=qt --harfbuzz=qt -no-opengl -linuxfb --xcb=no -tslib --libpng=qt --libjpeg=qt --sqlite=qt -plugin-sql-sqlite -I/opt/tslib/include -L/opt/tslib/lib -recheck-all executing config test machineTuple + arm-linux-gnueabi-g++ -dumpmachine > sh: 1: arm-linux-gnueabi-g++: not found test config.qtbase.tests.machineTuple FAILED executing config test verifyspec + cd /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/config.tests/verifyspec && /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/bin/qmake "CONFIG -= qt debug_and_release app_bundle lib_bundle" "CONFIG += shared warn_off console single_arch" 'QMAKE_LIBDIR += /opt/tslib/lib' 'INCLUDEPATH += /opt/tslib/include' -early "CONFIG += cross_compile" /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/config.tests/verifyspec + cd /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/config.tests/verifyspec && MAKEFLAGS= /usr/bin/make clean && MAKEFLAGS= /usr/bin/make > rm -f verifyspec.o > rm -f *~ core *.core > arm-linux-gnueabi-g++ -c -O2 -march=armv7-a -mtune=cortex-a7 -mfpu=neon -mfloat-abi=hard -O2 -march=armv7-a -mtune=cortex-a7 -mfpu=neon -mfloat-abi=hard -pipe -O2 -w -fPIC -I/home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/config.tests/verifyspec -I. -I/opt/tslib/include -I/home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/mkspecs/linux-arm-gnueabi-g++ -o verifyspec.o /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/config.tests/verifyspec/verifyspec.cpp > make:arm-linux-gnueabi-g++:命令未找到 > make: *** [Makefile:172:verifyspec.o] 错误 127
06-09

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值