Javascript 对json文件中的文本使用qsTr()

Javascript 对json文件中的文本使用qsTr(),javascript,json,qml,Javascript,Json,Qml,我正在使用qml,从json文件中获取一些信息,然后显示它。唯一的问题是我想做国际化。我已经尝试过使用qsTr(),但我无法通过从json文件获取信息来确定如何使其工作。以下是一个例子: JSON文件: {"information" : "Sample Text"} JavaScript文件 var read = JSON.parse(file) var info = qsTr(read.information) 但这不起作用,因为我必须直接在qsTr()中输入字符串。那么,有什么方法可以实

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

JSON文件:

{"information" : "Sample Text"}
JavaScript文件

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

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

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

这个问题发生在两个项目中,在其中一个项目中,我们刚刚更新了API,允许我请求字符串使用哪种语言,如果要正确翻译它们返回的字符串,则留给后端;然而,在另一个项目中,这不是一个选项(因为您从文件中解析它们,并且没有后端),所以我们选择做一些有点笨拙但有效的事情


在我开始之前,我建议一种更安全的方法可能是只在文件中存储ID(如消息代码),如果您要进行翻译,则将实际字符串保留在UI代码中,因为如果您稍后修改字符串(我将在下面解释),则更容易维护。如果这不是你的选择,那么试试下面的方法


< > C++中的qString()函数(或try-)函数采用一个字符串,并使用提供的字符串作为关键字,在翻译资源(*.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无法确定其开头或结尾,您的字符串“示例文本”将不在翻译资源文件中,因此qsTr()将找不到它的翻译版本,并默认为“示例文本”。但是,如果您只是确保*.qm文件包含字符串“Sample Text”的翻译以及正确的上下文,则将起作用

为了实现这一点,您只需在应用程序中的任何地方添加(以下在QML或C++代码中):

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

--旁注:另一个从文件读取的想法是,在运行lupdate后,您可以编写脚本或手动将字符串输入到*.ts文件中。请确保您的上下文匹配,下面将详细介绍上下文

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

例如:

QT_TRANSLATE_NOOP("MyDynamicStringsContext", "Sample Text")

var read = JSON.parse(file)
var info = qsTranslate("MyDynamicStringsContext", read.information)
现在,由于这都是静态完成的,很遗憾,您也不能对上下文字符串使用变量,它必须是字符串文字,但这样做的目的是确保字符串“Sample Text”显示在*.ts文件中,您的翻译人员可以为其提供翻译,并且您可以使用lrelease生成一个*.qm文件,该文件将包含键为“Sample Text”的“Sample Text”的翻译字符串和上下文“MyDynamicStringsContext”,以便qsTranslate()在运行时找到它

退一步说,正如我之前所说,这有点做作。它容易受到JSON调用另一端所做字符串更改的影响,从而破坏翻译;也就是说,如果另一端更改了大写(是的,这是区分大小写的),或者添加了标点符号,甚至是尾随空格,则字符串将不匹配,并且qsTranslate()将无法找到已翻译的字符串。这也意味着你需要提前知道所有可能的字符串,这样你就可以
QT_TRANSLATE_NOOP("MyDynamicStringsContext", "Sample Text")

var read = JSON.parse(file)
var info = qsTranslate("MyDynamicStringsContext", read.information)
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)