天天看点

从零开始学Qt(95):多语言界面设计概述

从零开始学Qt(95):多语言界面设计概述

有些软件需要开发多语言界面版本,如中文版和英文版,并且在软件里可以方便地切换界面语言。Qt为多语言界面提供了很好的支持,使用Qt的一些规则和工具,可以很方便地为应用程序开发提供多语言界面支持。

多语言界面开发步骤

用Qt开发多语言界面应用程序,主要包括以下几个步骤。

  • (1)在程序设计阶段,程序代码中每一个用户可见的字符串都用函数封装,以便Qt提取界面字符串用于生成翻译资源文件。用UI设计器可视化设计窗体时统一用一种语言,如汉语。
  • (2)在项目配置文件(.pro文件)中设置需要导出的翻译文件(.ts文件)名称,使用lupdate工具扫描项目文件中需要翻译的字符串,并生成翻译文件。
  • (3)使用Qt的Linguist程序打开生成的翻译文件,将程序中的字符串翻译为需要的语言,如将所有中文字符串翻译为英文。
  • (4)使用lrelease工具编译翻译好的翻译文件,生成更为紧凑的“.qm”文件。
  • (5)在应用程序中用Translator调用不同的“.qm”文件,实现不同的语言界面。

tr()函数的使用

为了让Qt能自动提取程序中用户可见的字符串,对于每个字符串都需要使用tr()函数封装。tr()是QObject的一个静态函数,在使用了Q_OBJECT宏定义的类或QObject的子类中,都可以直接使用tr()函数,否则需要使用QObject::tr()进行调用。或者在类定义中用Q_DECLARE_TR_ FUNCTIONS宏把tr()函数添加到类中之后,再直接调用tr()函数。tr()函数的定义是:

QString QObject::tr(const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1)           

其中,sourceText是源字符串,disambiguation是为翻译者提供额外信息的字符串,用于对一些容易混淆的地方作说明,内容如下:

LabCellPos = new QLabel (tr("当前单元格:"),this);
QMessageBox::information(this, tr("信息"),tr("信息提示?"),QMessageBox::Yes);
QString strl=tr("左右","大约的意思");
QString str2=tr("左右","掌握、控制的意思");           

使用tr()函数,需要注意以下一些事项。

  • 尽量使用常量字符串,不要使用字符串变量。在tr()函数中应直接传递字符串常量,而不是用变量传递字符串,如下面的代码使用了字符串变量,使用lupdate工具提取项目中的字符串时,将不能提取“不能删除记录”这个字符串。
char *errorStr="不能删除记录";
QString str2=tr(errorStr);           
  • 使用字符串变量时需要用Qt_TR_NOOP()宏进行标记。若要在tr()函数中使用字符串变量,需要在定义字符串的地方用Qt_TR_NOOP()宏进行标记,这在使用字符串数组时比较有用,例如:
const char *cities[4]={Qt_TR_NOOP("Beijing"),
  Qt_TR_NOOP("Shanghai"),
  Qt_TR_NOOP("Qingdao"),
  Qt_TR_NOOP("Wuhan") };
for (int i=0; i<4; i++)
	comboBox->addItem(tr(cities[i]));           
  • tr()不能使用拼接的动态字符串。tr()不能使用拼接的动态字符串,例如,下面的用法是错误的:
LabCellPos->setText(tr("第"+QString::number(current.row())+"行");           

正确的方式如下。

LabCellPos->setText(tr("第%1行").arg(current.row()));           

翻译的字符串是"第%1行",然后再用QString的arg()去替换占位符“%1”的内容。

  • Qt_NO_CAST_FROM_ASCII的作用。在一个需要翻译为多语言的应用程序中,如果编写程序时忘了对某个字符串使用tr()函数,lupdate生成的翻译资源文件就会遗漏这个字符串。为了避免这种疏忽错误,可以在项目配置文件(.pro文件)中添加如下的定义:
DEFINES += Qt_NO_CAST_FROM_ASCII           

这样在编译时,会禁止从const char*到QString的隐式转换,强制每个字符串都必须使用tr()或QLatinlString()封装,避免出现遗漏未翻译的字符串。

下一篇文章给出示例程序。

————————————————

觉得有用的话请关注点赞,谢谢您的支持!

对于本系列文章相关示例完整代码有需要的朋友,可关注并在评论区留言!

继续阅读