在json文件中的文本上使用qsTr()

时间:2015-05-28 19:20:24

标签: javascript json qml

我正在使用qml,我从json文件中获取一些信息,然后显示它。唯一的问题是我想做国际化。我尝试过使用qsTr(),但我无法通过从json文件中获取信息来弄清楚如何使其工作。这是一个例子:

JSON文件:

{"information" : "Sample Text"}

JavaScript文件

var read = JSON.parse(file)
var info = qsTr(read.information)

但这不起作用,因为我必须直接在qsTr()中输入字符串。那么我有什么办法可以在info变量上实现国际化吗?

1 个答案:

答案 0 :(得分:1)

我最近在处理一个项目时遇到了同样的问题,但我正在编写一个产品的前端,该产品通过JSON格式的API调用与后端进行通信。一些面向用户的字符串是通过JSON调用来自后端的。

这个问题出现在两个项目中,其中一个我们刚刚更新了API,允许我请求哪个语言我想要字符串,如果到后端正确翻译他们返回的字符串就离开了;但是,在另一个项目中,这不是一个选项(并且它不是你的一个选项,因为你从文件中解析它们并且没有后端)所以我们选择做一些有点蠢事但是它有效。

在我进入之前,我建议更安全的approch可能只是在您的文件中存储ID(如消息代码),如果您要进行翻译,则将实际字符串保留在UI代码中,因为如果您更容易维护最后修改字符串(我将在下面解释)。如果这不是您的选择,请尝试以下操作。

qsTr()函数(或C ++中的tr()函数)接受一个字符串并使用提供的字符串在翻译资源(* .qm)文件中查找以查找翻译版本。此可以使用字符串文字 字符串变量。

假设翻译存在于* .qm文件中,以下两项都将在运行时起作用:

Text { text: qsTr("Hello World"); }
Text {
    property string unTranslatedString: "Hello World"
    text: qsTr( unTranslatedString )
}

问题在于,用于生成Qt用于国际化的* .ts和* .qm文件的lupdate和lrelease工具不会理解字符串变量。 lupdate逐行静态梳理你的代码文件并查找qsTr()或tr()方法中包含的任何字符串,并将它们提取到* .ts文件中,这是一个XML文件,翻译人员可以使用它来生成列表在应用程序中找到的每个可翻译字符串的翻译。这是在未编译的代码上完成的,因此它无法理解变量,因为它无法在运行时知道变量中存储了哪些字符串。这就是为什么文档说你只能使用带有qsTr()和tr()的字符串文字以及为什么lupdate在遇到使用变量而不是字符串文字的qsTr()/ tr()语句时会给你警告的原因;但是, qsTr()/ tr()将使用存储在变量中的字符串来查找翻译。

上面的代码示例将 解决的问题是,因为lupdate无法使用它的字符串或#34;示例文本&#34 ;不会在您的翻译资源文件中,因此qsTr()无法找到它的翻译版本,默认为" Sample Text"。但是,如果您只是确保您的* .qm文件包含字符串的翻译"示例文本"在正确的背景下, 工作。

要实现这一点,您只需在应用程序的任何位置添加以下内容(在QML或C ++代码中):

QT_TR_NOOP("Sample Text");

它是一个宏,它接受一个字符串,但进行翻译查找,它将返回未翻译的字符串。如果你只是把它放在你的项目中的某个地方,lupdate将获取字符串,它会扫描qsTr(),tr(),QT_TR_NOOP()和其他类似的函数/宏,并将它放在* .ts文件和所有字符串中运行lrelease时,* .ts文件将添加到* .qm文件中。 QT_TR_NOOP()宏甚至不需要在运行时由您的应用程序执行,因为它仅用于确保在预编译时将动态字符串添加到转换文件中。

- 旁边注意另一个想法,因为你从文件中读取的是你可以编写脚本或在运行lupdate后手动将字符串输入* .ts文件,只需确保你的上下文匹配,更多关于下面的上下文。 / p>

要记住的一件事是,Qt的翻译系统使用上下文来确保如果你在两个不同的视图上有相同的单词,但在视图上它有不同的含义然后在视图2上你可以提供根据语境,在某些语言中对两个单词进行不同的翻译。使用qsTr()/ tr()时,将使用类名自动定义上下文。因此,如果您的QML代码在一个文件中并且您将QT_TR_NOOP()宏放在另一个文件中,那么它们将具有不同的上下文,这将导致您的代码不起作用,它们是相同的字符串但在不同的上下文中。要显式设置给定字符串的上下文,请使用QT_TRANSLATE_NOOP()和qsTranslate()。

示例:

QT_TRANSLATE_NOOP("MyDynamicStringsContext", "Sample Text")

var read = JSON.parse(file)
var info = qsTranslate("MyDynamicStringsContext", read.information)

现在因为这完全是静态完成的,你不能使用变量作为上下文字符串,它必须是字符串文字,但这样做是为了确保字符串"示例文本&# 34;显示在您的* .ts文件中,您的翻译人员可以为其提供翻译,您可以生成带有lrelease的* .qm文件,该文件将包含"示例文本"使用键"样本文本"和上下文" MyDynamicStringsContext"为了让qsTranslate()在运行时找到它。

退缩是因为我之前说的这有点过分了。它很容易受到JSON调用另一端完成的字符串更改而破坏了翻译;也就是说,如果另一端更改大小写(是的,这是区分大小写)或添加标点符号甚至是尾随空格,字符串不会匹配,qsTranslate()将无法找到已翻译的字符串。这也意味着您需要提前知道所有可能的字符串,以确保您有翻译。所以这个例子看起来更像是这样:

QT_TRANSLATE_NOOP("MyDynamicStringsContext", "Sample Text")
QT_TRANSLATE_NOOP("MyDynamicStringsContext", "Sample Text ")
QT_TRANSLATE_NOOP("MyDynamicStringsContext", "sample text")
QT_TRANSLATE_NOOP("MyDynamicStringsContext", "Other Possible Sample Text")


var read = JSON.parse(file)
var info = qsTranslate("MyDynamicStringsContext", read.information)

哦,最后lupdate会在每次碰到qsTranlate()语句时尖叫着你,该语句包含变量,因为它不知道如何处理它并将忽略它。这是好的,因为你知道你已经覆盖了它,但你可能最终淹没在警告信息中并错过了一些合法的问题。

所以它很脆弱,但是如果你对两端都有合理的控制权,那么这是一个选择,但却无法将字符串翻译到后端。

我希望能帮到你并回答你的问题

直到下一次富有想象力地思考并创造性地设计