Qt学习之路(34):国际化(下)

上次说了国际化的过程,现在来看一下具体的国际化的相关代码。

在代码中,我们使用tr()将需要翻译的字符串标记出来。lupdate工具就是提取出tr()函数中的相关字符串。tr()函数是QObject类的一个static函数,其签名如下:

static QString tr(const char *sourceText, const char *comment = 0, int n = -1);

虽然我们只传了一个参数,但是实际上tr()函数是接受3个参数的。第一个参数是我们需要翻译的文字,如果使用qm文件有对应的字符串,则使用对应的字符串进行替换,否则将显示sourceText参数指定的字符串。第二个参数是一个注释,用于解释前面的sourceText的含义,比如 table一词既可以当做桌子翻译,又可以当成表格翻译,这时你就需要提供这个注释。或许你会问,使用翻译工具的时候不是有源代码吗?问题是,有可能人家不使用这个翻译工具,而使用别的工具,这样就不能保证会有这个源代码的预览;并且,你的程序不一定必须要发布源代码的;翻译人员往往只得到我们导出的ts 文件,如果你加上注释,就可以方便翻译人员进行翻译。最后一个参数n用于指定字符串是否为复数。我们知道,很多语言,比如英语,很多名词的单复数形式是不相同的,为了解决这个问题,Qt在tr()函数中提供了一个参数n。请看如下代码:

int n = messages.count();
showMessage(tr("%n message(s) saved", "", n));

对于n的值的不同,Qt会翻译成不同的文字,例如:

 n  翻译结果 
 0  0 message saved 
 1  1 message saved
 2  2 messages saved
 5  5 messages saved

tr()函数是QObject的函数,如果你的类不是继承自QObject,就不能直接使用tr()函数。比如我们在main()函数中希望增加一句设置MainWindow的title的代码:

w.setWindowTitle(tr("MyApp"));

直接这样写是无法通过编译的,因为main()函数是全局函数,所以这个tr()是找不到的。解决办法一是显式地调用QObject的函数:

w.setWindowTitle(QObject::tr("MyApp"));

或者,你可以使用QCoreApplication的translate()函数。你一定还记得,我们的main()函数的第一句总是 QApplication app;,其实,QApplication就是QCoreApplication的子类。所以,我们也能这样去写:

w.setWindowTitle(app.translate("MyApp"));

由于在Qt程序中,QCoreApplication是一个单例类,因此,Qt提供了一个宏qApp,用于很方便的访问 QCoreApplication的这个单例。所以,在其他文件中,我们也可以直接调用qApp.translate()来替换tr(),不过这并没有必要。

如果你的翻译文本中包含了需要动态显示的数据,比如我们上次代码中的

QMessageBox::information(NULL, tr("Path"), tr("You selected\n%1").arg(path));

这句你当然可以写成

QMessageBox::information(NULL, tr("Path"), "You selected\n" + path);

但这种连接字符串的方式就不能够使用tr()函数了!因此,如果你需要像C语言的printf()函数这种能够格式化输出并且需要翻译时,你必须使用我们例子中的%1加arg()函数!

时间: 2025-01-02 09:22:05

Qt学习之路(34):国际化(下)的相关文章

Qt学习之路(33):国际化(上)

2D绘图部分基本告一段落,还在想下面的部分要写什么,本来计划先说下view-model的相关问题,但是前面看到有朋友问关于国际化的问题,所以现在先来说说Qt的国际化吧! Qt中的国际化的方法有很多,常用的有使用QTextCodec类和使用tr()函数.前者将编码名称写到代码里面,除非你使用Unicode 编码,否则国际化依然是一个问题:后者就不会有这个问题,并且这也是Qt推荐的做法.因此,我们主要来说使用tr()函数的方法进行应用程序的国际化. 我们先来看一个很简单的MainWindow.为了清

Qt 学习之路 2 --- 读书笔记

一.文章来由 来自豆子老师非常好的一本Qt教程,但是只有网络版,所以用这个做笔记了,不动笔墨不读书嘛~~ 二.读书笔记 1.Qt 学习之路 2(2):Qt 简介 1.1 关于 Qt 的一站式解决 Qt 是一个著名的 C++ 应用程序框架.但并不只是一个 GUI 库,因为 Qt 十分庞大,并不仅仅是 GUI 组件.使用 Qt,在一定程度上你获得的是一个"一站式"的解决方案:不再需要研究 STL,不再需要 C++ 的,不再需要到处去找解析 XML.连接数据库.访问网络的各种第三方库,因为

Qt学习之路(23):自定义事件

Qt允许你创建自己的事件类型,这在多线程的程序中尤其有用,当然,也可以用在单线程的程序中,作为一种对象间通讯的机制.那么,为什么我需要使用事件,而不是使用信号槽呢?主要原因是,事件的分发既可以是同步的,又可以是异步的,而函数的调用或者说是槽的回调总是同步的.事件的另外一个好处是,它可以使用过滤器. Qt中的自定义事件很简单,同其他类似的库的使用很相似,都是要继承一个类进行扩展.在Qt中,你需要继承的类是QEvent.注意,在Qt3中,你需要继承的类是QCustomEvent,不过这个类在Qt4中

Qt学习之路(2):Hello,world!

任何编程技术的学习第一课基本上都会是Hello, world!,我也不想故意打破这个惯例--照理说,应该首先回顾一下Qt的历史,不过即使不说这些也并无大碍. 或许有人总想知道,Qt这个单词是什么意思.其实,这并不是一个缩写词,仅仅是因为它的发明者,TrollTech公司的 CEO,Haarard Nord和Trolltech公司的总裁Eirik Chambe-Eng在联合发明Qt的时候并没有一个很好的名字.在这里,字母Q是Qt库中所有类的前缀--这仅仅是因为在Haarard的emacs的字体中,

Qt学习之路(8):创建一个对话框(下)

接着前一篇,下面是源代码部分: #include <QtGui> #include "finddialog.h" FindDialog::FindDialog(QWidget *parent) : QDialog(parent) { label = new QLabel(tr("Find &what:")); lineEdit = new QLineEdit; label->setBuddy(lineEdit); caseCheckBox

Qt学习之路(11):MainWindow

尽管Qt提供了很方便的快速开发工具QtDesigner用来拖放界面元素,但是现在我并不打算去介绍这个工具,原因之一在于我们的学习大体上是依靠手工编写代码,过早的接触设计工具并不能让我们对Qt的概念突飞猛进-- 前面说过,本教程很大程度上依照的是<C++ GUI Programming with Qt4, 2nd Edition>这本书.但是,这本书中接下来的部分用了很大的篇幅完成了一个简单的类似Excel的程序.虽然最终效果看起来很不错,但我并不打算完全依照这个程序来,因为这个程序太大,以至于

Qt学习之路(1):前言

我们所使用的Qt,确切地说也就是它的GUI编程部分.C++的GUI编程同Java不同:GUI并不是C++标准的一部分.所以,如果使用Java,那么你最好的选择就是AWT/Swing,或者也可以使SWT/JFace,但是,C++的GUI编程给了你更多的选择:wxWidget, gtk++以及Qt.这几个库我都有接触,但是接触都不是很多,只能靠一些资料和自己的一点粗浅的认识说一下它们之间的区别(PS: 更详尽的比较在前面的文章中有). 首先说wxWidget,这是一个标准的C++库,和Qt一样庞大.

Qt学习之路(29):绘图设备

绘图设备是指继承QPainterDevice的子类.Qt一共提供了四个这样的类,分别是QPixmap.QBitmap.QImage和 QPicture.其中,QPixmap专门为图像在屏幕上的显示做了优化,而QBitmap是QPixmap的一个子类,它的色深限定为1,你可以使用 QPixmap的isQBitmap()函数来确定这个QPixmap是不是一个QBitmap.QImage专门为图像的像素级访问做了优化. QPicture则可以记录和重现QPainter的各条命令.下面我们将分两部分介绍

Qt学习之路(28):坐标变换

经过前面的章节,我们已经能够画出一些东西来,主要就是使用QPainter的相关函数.今天,我们要看的是QPainter的坐标系统. 同很多坐标系统一样,QPainter的默认坐标的原点(0, 0)位于屏幕的左上角,X轴正方向是水平向右,Y轴正方向是竖直向下.在这个坐标系统中,每个像素占据1 x 1的空间.你可以把它想象成是一张坐标值,其中的每个小格都是1个像素.这么说来,一个像素的中心实际上是一个"半像素坐标系",也就是说,像素(x, y)的中心位置其实是在(x + 0.5, y +