Qt 5.5 中Qt Script翻译 (九)

接着上一章

重定义print()

QtScript提供了一个内建的print()函数可用作简单的调试打印,内建的print()写到标准输出,你能重定义print()(或者添加自己的函数,例如debug()或者log())用于重定向,下面的代码显示了一个自定义的print()重定向到QPlainTextEdit.

 QScriptValue myPrintFunction(QScriptContext *context, QScriptEngine *engine)
  {
      QString result;
      for (int i = 0; i < context->argumentCount(); ++i) {
          if (i > 0)
              result.append(" ");
          result.append(context->argument(i).toString());
      }

      QScriptValue calleeData = context->callee().data();
      QPlainTextEdit *edit = qobject_cast<QPlainTextEdit*>(calleeData.toQObject());
      edit->appendPlainText(result);

      return engine->undefinedValue();
  }

下面的代码是关于自定义print()函数的自定义方式

int main(int argc, char **argv)
  {
      QApplication app(argc, argv);

      QScriptEngine eng;
      QPlainTextEdit edit;

      QScriptValue fun = eng.newFunction(myPrintFunction);
      fun.setData(eng.newQObject(&edit));
      eng.globalObject().setProperty("print", fun);

      eng.evaluate("print('hello', 'world')");

      edit.show();
      return app.exec();
  }

QPlainTextEdit是被存储到脚本函数的自定义属性内部,当函数被调用时QPlainTextEdit能被找到。

Qt脚本扩展

QtScriptEngine::importExtension()函数用来加载插件到脚本引擎当中,插件添加一些额外的功能到引擎当中,例如:插件可能会提供所有的Qt亚瑟绘画API到脚本当中,使Qt脚本可以使用这些绘制类,目前没有脚本插件与QT一起发布。

如果你想开发一些Qt脚本功能提供给其他的Qt开发人员,developing an extension(例如,需要子类化QScriptExtensionPlugin)值得一看。

国际化

自从Qt4.5开始,Qt脚本支持国际化,Qt脚本支持C++国际化功能可以参考(Internationalization with Qt).

对原文本使用qsTr()功能

无论你的脚本使用什么文本“quoted text”显示给用户,确保可以通过QCoreApplication::translate()函数处理。实现这一点所必需的是使用qrTr()脚本函数。

myButton.text = qsTr("Hello world!");

这种写法占用户可看见的字符串的99%。

qsTr用脚本的名称作为转换的上下文,如果文件名称在你的脚本工程当中是不是唯一的文件名称,你需要使用qsTranslate()函数并且传递一个合适的参数,例如:

myButton.text = qsTranslate("MyAwesomeScript", "Hello world!");

如果你需要在函数外翻译文本,这里有两个函数可以帮助你,QT_TR_NOOP() 和 QT_TRANSLATE_NOOP().它们仅仅标记了下面描述的lupdate实用程序提取文本。在运行时,这些函数简单地返回文本以进行未修改的翻译。

QT_TR_NOOP():的例子

FriendlyConversation.prototype.greeting = function(type)
  {
      if (FriendlyConversation['greeting_strings'] == undefined) {
          FriendlyConversation['greeting_strings'] = [
              QT_TR_NOOP("Hello"),
              QT_TR_NOOP("Goodbye")
          ];
      }
      return qsTr(FriendlyConversation.greeting_strings[type]);
  }

QT_TRANSLATE_NOOP():的例子

FriendlyConversation.prototype.greeting = function(type)
  {
      if (FriendlyConversation['greeting_strings'] == undefined) {
          FriendlyConversation['greeting_strings'] = [
              QT_TRANSLATE_NOOP("FriendlyConversation", "Hello"),
              QT_TRANSLATE_NOOP("FriendlyConversation", "Goodbye")
          ];
      }
      return qsTranslate("FriendlyConversation", FriendlyConversation.greeting_strings[type]);
  }

动态文本用String.prototype.arg()

String.prototype.arg()函数提供了简单的替换方法

 FileCopier.prototype.showProgress = function(done, total, currentFileName)
  {
      this.label.text = qsTr("%1 of %2 files copied.\nCopying: %3")
                        .arg(done)
                        .arg(total)
                        .arg(currentFileName);
  }

制作翻译

一旦在整个脚本中使用了qsTr()和/或qsTranslate(),就可以开始生成程序中用户可见文本的翻译。

Qt语言手册提供了关于Qt的翻译工具、Qt语言工具、lupdate和lrelease的进一步信息。

QT脚本翻译需要执行下面三个过程:

1、运行lupdate获取从脚本源码文件中转换的文本,转换的结果将存储在一个ts文件中,综合运用
 qsTr(), qsTranslate()和 QT_TR*_NOOP()函数生成ts文件(通常每种语言一个ts文件)。

2、准备ts类型的转换文件,用Qt Linguist对ts文件翻译,因为ts文件是xml格式的,你也可以手动编辑。

3、运行lrelease从TS文件中获取轻量级消息文件(QM文件),qm文件仅适合于最终使用。将TS文件视为“源文件”,并将QM文件视为“目标文件”。翻译器编辑TS文件,但是应用程序的用户只需要QM文件。这两种文件都是独立的平台和区域。

典型的应用,你需要在你的每个应用程序中重复这些步骤,lupdate实用程序尽其所能重用以前版本的翻译。

运行lupdate,你必须指定本地的脚本文件,提供一个生成的ts的文件名,例如:

lupdate myscript.qs -ts myscript_la.ts

从myscript.qs中提取转换文件,生成要转换的myscript_la.ts文件。

lupdate -extensions qs scripts/ -ts scripts_la.ts

从scripts文件加下提取所有的以.qs结尾的文件,生成一个转换文件scripts_la.ts。

或者,你能创建一个分离的qmake工程文件,并设置合适的SOURCES和TRANSLATIONS变量,将工程文件作为lupdate的输入。

lrelease myscript_la.ts

当运行lrelease时你必须指定ts文件的名字,或者,如果你用qmake工程文件管理脚本转换,你制定工程文件名,lrelease将生成myscript_la.qm文件,这是一个二进制的转换文件。

使用语言转换文件

在你的应用程序当中,你需要使用Qt::Translator::load()加载合适的用户语言文件,并用QCoreApplication::installTranslator()安装他们,最后,你必须调用QScriptEngine::installTranslatorFunctions(),这样才能使用脚本语言转换函数(qsTr(), qsTranslate()和QT_TR*_NOOP()),在脚本中使用qsTr(),必须将合适的文件名称传递到QScriptEngine::evaluate()的第二个参数。

linguist, lupdate 和 lrelease是被安装在Qt下的bin子目录中,点击Qt Linguist下的Help|Manual可以查看用户手册,手册中讲述了怎样开始。

查看Hello Script Example.

与ECMAScript标准的兼容性问题

Qt脚本中实现了所有的ECMA-262标准的对象和属性,查看ECMAScript reference相关的标准概述

Qt Script 对ECMAScript进行了扩展

1、__proto__

在脚本代码中 一个object的prototype(QScriptValue::prototype())可以通过__proto__ 属性访问,这个属性中含有 QScriptValue::Undeletable标记,例如:

 var o = new Object();
  (o.__proto__ === Object.prototype); // this evaluates to true

2、Object.prototype.__defineGetter__ 

在object的prototype中添加一个getter函数,第一个参数是属性名称,第二个参数是获取属性值的函数,当调用这个函数时,this将是被访问的属性的对象,例如:

var o = new Object();
  o.__defineGetter__("x", function() { return 123; });
  var y = o.x; // 123

3、Object.prototype.__defineSetter__ 

在object的prototype中添加一个setter函数,第一个参数是属性名称,第二个参数是设置属性值的函数,当调用这个函数时,this将是被访问的属性的对象,例如:

 var o = new Object();
  o.__defineSetter__("x", function(v) { print("and the value is:", v); });
  o.x = 123; // will print "and the value is: 123"

4、Function.prototype.connect 

这个函数会链接一个信号到一个槽,在Using Signals and Slots章节中描述了这个函数的用法 。

5、Function.prototype.disconnect

这个函数会结束一个信号的链接,在Using Signals and Slots章节中描述了这个函数的用法 。

6、QObject.prototype.findChild 

这个函数的用法与QObject::findChild()相同。

7、QObject.prototype.findChildren 

这个函数的用法与QObject::findChildren()相同。

8、QObject.prototype.toString

这个函数返回QObject的默认字符串

9、gc 

这个函数调用垃圾回收

10、Error.prototype.backtrace 

这个函数返回手动读取backtrace的结果,是一个字符串数组。

11、Error objects中还有额外的属性:lineNumber:错误发生的行数,fileName错误发生的文件名(如果
QScriptEngine::evaluate()中传入了文件名)。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值