- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
在Qt中,所有的输入部件和文本绘制方式对Qt支持的所有语言都提供了内置的支持。Qt内置的字体引擎可以在同一时间正确而且精细地绘制不同的文本,这些文本可以包含来自众多不同书写系统的字符。如果想了解更多的相关知识,可以在帮助中通过Overview of the Translation Process
关键字查看。
Qt对把应用程序翻译为本地语言提供了很好的支持,可以使用Qt Linguist
工具完成应用程序的翻译工作,这个工具在第1章就已经介绍过了,这里将进一步介绍。
这一小节先通过一个简单的例子介绍Qt中翻译应用程序的整个过程,然后再介绍其中需要注意的方面,这部分内容可以通过Qt Linguist Manual
关键字查看。在Qt中编写代码时要对需要显示的字符串调用tr()函数
,完成代码编写后对这个应用程序的翻译主要包含3步:
①运行lupdate工具,从C++源代码中提取要翻译的文本,这时会生成一个.ts文件,这个文件是XML格式的;
②在Qt Linguist 中打开.ts文件,并完成翻译工作;
③运行lrelease工具,从.ts文件中获得.qm文件,它是一个二进制文件。这里的.ts文件是供翻译人员使用的,而程序运行时只需要使用.qm文件,这两个文件都是与平台无关的。
下面通过一个简单的例子来介绍整个翻译过程,该例子实现了将一个英文版本的应用程序翻译为简体中文版本。
下面再使用代码添加几个标签,打开mainwindow.cpp文件,添加头文件#include < QLabel>,然后在构造函数中添加代码:
QLabel *label = new QLabel(this);
label->setText(tr("hello Qt!"));
label->move(100,50);
QLabel *label2 = new QLabel(this);
label2->setText(tr("password", "mainwindow"));
label2->move(100,80);
QLabel *label3 = new QLabel(this);
int id = 123;
QString name = "yafei";
label3->setText(tr("ID is %1,Name is %2").arg(id).arg(name));
label3->resize(150, 12);
label3->move(100, 120);
这里向界面上添加了3个标签,因为这3个标签中的内容都是用户可见的,所以要调用tr()函数。在label2中调用tr()函数时还使用了第二个参数,其实, tr()函数共有3个参数,它的原型如下:
QString Q0bject::tr(const char* sourceText,const char *disambiguation= Q_NULILPTR,int n =-1)[static]
第一个参数 sourceText
就是要显示的字符串, tr()函数会返回sourceText 的译文。
第二个参数 disambiguation
是消除歧义字符串,比如这里的password,如果一个程序中需要输入多个不同的密码,那么在没有上下文的情况下就很难确定这个password到底指哪个密码。这个参数一般使用类名或者部件名,比如这里使用了mainwindow,就说明这个password是在 mainwindow上的。
第三个参数n
表明是否使用了复数,因为英文单词中复数一般要在单词末尾加“s”,比如“1 message”,复数时为“2messages”。遇到这种情况,就可以使用这个参数,它可以根据数值来判断是否需要添加“s”,例如:
int n = messages.count();
showMessage(tr("%n message(s) saved","",n));
tr()函数3个参数更多的用法介绍可以在帮助中通过 Writing Source CodeTranslation
关键字查看。
打开myl18N.pro 文件,在最后面添加如下一行代码;
TRANSLATIONS = myI18N_zh_CN.ts
这就表明生成的.ts文件的文件名是以myI18N_zh_CN.ts
可以随便写,这里的_zh_CN是为了表示简体中文
最后crts+s保存
3.第三步,使用lupdate生成.ts文件。当要进行翻译工作时,先要使用lupdate工具来提取源代码中的翻译文本,生成. ts文件。
选择“工具→外部→Qt语言家→更新翻译(lupdate)”菜单项
从概要信息输出栏中可以看到,更新了myll8N_zh_CN.ts文件,发现了8个源文本,其中有8条新的翻译和0条已经存在的翻译。
这表明可以对程序代码进行更改,然后多次运行lupdate,而只需要翻译新添加的内容。
可以在项目目录中使用写字板打开这个.ts文件,可以看到它是XML格式的,其中记录了字符串的位置和是否已经被翻译等信息。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
<context>
<name>MainWindow</name>
<message>
<location filename="mainwindow.ui" line="14"/>
<source>MainWindow</source>
<translation>应用程序主窗口</translation>
</message>
<message>
<location filename="mainwindow.ui" line="27"/>
<source>PushButton</source>
<translation>按钮</translation>
</message>
<message>
<location filename="mainwindow.ui" line="42"/>
<source>&File</source>
<translation>文件(&F)</translation>
</message>
<message>
<location filename="mainwindow.ui" line="59"/>
<source>&New</source>
<translation>新建(&N)</translation>
</message>
<message>
<location filename="mainwindow.ui" line="62"/>
<source>Ctrl+N</source>
<translation>Ctrl+N</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="12"/>
<source>hello Qt!</source>
<translation>你好 Qt!</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="16"/>
<source>password</source>
<comment>mainwindow</comment>
<translation>密码</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="22"/>
<source>ID is %1,Name is %2</source>
<translation>账号是%1,名字是%2</translation>
</message>
</context>
</TS>
在系统的开始菜单(Qt 5.6.0分类下)启动Linguist(打开Linguist的方法),然后单击界面左上角的打开图标(快捷键Ctrl+O),在弹出的文件对话框中进入项目目录,打开 myIl8N_ zh_CN文件,这时整个界面如图所示。QtLinguist窗口主要由以下几部分组成:
上下文窗口
翻译区域
短语和猜测
警告窗口
下面来翻译程序。在翻译区域可以看到现在已经是要翻译成汉语,这是因为. ts文件名中包含了中文的区域代码。
如果这里没有正确显示要翻译成的语言,那么可以使用“编辑→翻译文件设置”菜单项来更改。
下面首先对 Main Window进行翻译,在汉语译文处翻译为“应用程序主窗口”,然后按下Ctrl+Return(即回车键)完成翻译并开始翻译第二个字符串。
按照这种方法完成所有字符串的翻译工作,如表所列,其中的一些翻译问题放到下一节再讲。
翻译完成后按下Ctrl+S保存更改。这里对Qt Linguist只是进行了简单的介绍,详细内容可以在帮助中通过Qt Linguist Manual:Translators
关键字查看。
还可以通过Qt Creator的“工具→外部→Qt语言家→发布翻译(lrelease)”菜单项来完成。
QTranslator translator;
translator.load("../myI18N/myI18N_zh_CN.qm");
a.installTranslator(&translator);
…表示当前项目工程目录,使用了相对路径
为QApplication a对象使用了翻译
注意,这几行代码一定要放到创建部件的代码之前
比如这里放到了“Main Window;”一行代码之前
这样才能对该部件进行翻译。另外,有时可能因为部件的大小问题使得翻译后的文本无法完全显示,较好地解决方法就是使用布局管理器。
现在可以运行程序查看效果。
项目程序代码:代码我就不贴了
项目
因为QString内部使用了Unicode编码,所以世界上所有的语言都可以使用熟悉的文本处理操作来进行处理。而且,因为所有的Qt函数都使用QString 作为参数来向用户呈现文本内容,所以没有char *到QString的转换开销。
无论什么时候使用要呈现给用户的文本,都要使用tr()函数进行处理
LoginWidget::LoginWidget()
{
QLabel*label=new QLabel(tr("Password:"));
}
如果引用的文本没有在QObject子类的成员函数中
,那么可以使用一个合适的类的tr函数,或者直接使用QCoreApplication::translate()
函数。
void some_global_function(LoginWidget *logwid)
{
QLabel* label=new QLabel(
LoginWidget::tr("Password:"),logwid);
}
void some_global_function(LoginWidget *logwid)
{
QLabel* label=new QLabel(
qApp->translate("LoginWidget","Password:"),logwid);
}
如果要在不同的函数中使用要翻译的文本,那么可以使用QT_TR_NOOP()
宏和QT_TRANSLATE_NOOP()
宏,它们仅仅对该文本进行标记来方便lupdate工具提取。
使用QT_TR_NOOP()
的例子:
QString FriendlyConversation::greeting(int type)
{
static const char *greeting_strings[] ={
QT_TR_NOOP("Hello"),
QT_TR_NOOP("Goodbye")
};
return tr(greeting_strings[type]);
}
使用QT_TRANSLATE_NOOP()
的例子:
static const char * greeting_strings[]=
{
QT_TRANSLATE_NOOP("FriendlyConversation" ,"Hell1o"),
QT_TRANSLATE_NOOP("FriendlyConversation","Goodbye")
};
QString FriendlyConversation::greeting(int type)
{
return tr(greeting_strings[type]);
}
QString global_greeting(int type)
{
return qApp->translate("FriendlyConversation",
greeting_strings[type]);
}
类似于Ctrl+Q或者Alt+F等加速键的值也需要被翻译。如果使用了硬编码的Qt::CTRL+Qt::Key_Q作为退出操作的快捷键,那么翻译将无法覆盖它。正确的习惯用法为:
exitAct=new QAction(tr("E&xit"),this);
exitAct->setShortcuts(QKeySequence::Quit);
对于字符串中使用arg()函数添加的变量,其中的%1、%2等参数的顺序在翻译时可以改变,它们对应的值不会改变。
QTextCodec
类以及QTextStream
使得Qt可以很容易地支持大量用户数据的输入和输出编码。当一个应用程序启动时,机器的语言环境便会决定处理8位数据(例如,字体选择、文本显示,8位文本I/O和字符输入等)时使用的8位编码。
应用程序有时也需要使用默认的本地8位编码以外的编码,例如,使用ISO 8859 -5编码,代码如下:
QString string=.....; //一些Unicode文本
//换编码格式
QTextCodec *codec=QTextCodec::codecForName("ISO 8859-5");
QByteArray encodedString=codec->fromUnicode(string);
如果要将Unicode转换为本地8位编码,那么可以使用QString::toLocal8Bit()
函数;
还有一个QString :: toUtf8()
函数可以返回使用8位UTF-8编码的文本。
要将其他编码转换为Unicode编码,那么可以使用QTextCodec类的 toUnicode()函数,还有QString : : fromUtf8()和QString : : fromLocal8Bit()等。
使用QTextCodec::codecForLocale()
返回的编码是最重要的一个编码,因为这个是用户与他人或者其他应用程序进行通信最有可能使用的编码。
如果要使一个类中的字符串支持国际化,那么该类或者继承自QObject类或者使用Q_OBJECT宏。而对于非Qt类,如果要支持翻译,需要在类定义的开始使用Q_DECLARE_TR_FUNCTIONS()
宏,例如:
class MyClass
{
Q_DECLARE_TR_FUNCTIONS(MyClass)
public:
MyClass();
....
};
这样就可以在该类中使用tr函数了
如果在一个程序中提供了多种语言选择,那么最好的方法就是在程序启动时判断本地的语言环境,然后加载对应的.qm文件。
可以使用QLocale::system().name()
来获取本地的语言环境,它会返回QString
类型的“语言_国家”格式的字符串,其中的语言
用两个小写字母表示,符合ISO 639编码;国家
使用两个大写字母表示,符合ISO3166国家编码。例如,中国简体中文的表示为“zh_CN”.
可以使用这个返回值来调用不同的文件,使应用程序自动使用相应的语言。
国际化中还有本地化,在应用程序运行时动态进行语言更改等内容,这里就不再介绍,感兴趣的读者可以在帮助中通过Internationalization
关键字参考。
我正在尝试创建一个简单的小部件,它只有一个切换按钮,但我的 AVD 模拟器上不断出现错误,提示“加载小部件有问题”。 似乎是因为我在小部件布局中添加了开关或切换按钮。 为了测试它,我创建了一个新的空
我正在使用 GLFW 进行键盘输入,但处理速度太快,因此我的 bool 开关在一次按下时被更改了 10 次,因为输入是每一帧处理的。我只需要按一次空格键即可切换状态。我当前的代码如下: if (glf
我希望完成一个相当简单的任务(我希望!) 我有两个 div 标签和一个 anchor 标签,像这样: forgot password? 我希望使用 anchor 标记在两个 div 标记之间切换,
我已经尝试了几种不同的方法,但似乎无法弄清楚如何将 span 的类从“die2”切换到“die3”以及将 div 的显示样式从“block”切换到“none”。有人有任何解决方案吗? (基本上当页面加
我正在尝试制作一个交换小部件,该小部件显示两个不同的文本。激活时,它下面显示一个TextField,顶部是不可见的,而禁用时它上面显示一个Text,而底部是不可见。但是它没有在屏幕上显示任何内容,只是
我有一个简单的 Angular 应用程序,它使用两个模板和 Controller 。放置两个按钮来切换 View 。它们调用在控件内定义的函数,该函数使用 window.location='' 来切换
我想要一个 div 切换它的类(切换)onclick,然后再次恢复到原来的类 onclick 我的代码是: function myfunc() { //the code over here
我确信这是一个常见问题,我已经尝试了该网站上的许多线程来尝试解决我的问题,但我似乎无法使其正常工作。基本上我有一个子菜单,当父菜单悬停在其上时需要显示该子菜单,但是如果您在加载完成之前将鼠标从菜单项上
我制作了一个 JavaScript 函数来隐藏单击按钮时的链接及其在该函数中的工作 function toggle() { var ele = document.getElement
我正在使用我在 JS fiddle 上找到的这个脚本:http://jsfiddle.net/Q4PUw/2/ 当我点击切换链接时,它会切换框并显示它,但是,它会跳回页面顶部,然后我必须再次向下滚动才
我正在 GoDaddy 上的共享服务器 IP 上构建 Web 应用程序。该应用程序与验证请求服务器 IP 的房地产 API 进行对话。问题是在 GoDaddy 上,我们的 IP 被列为 X,但它实际上
我在 jquery 中有一个简单的脚本,可以在 时切换 div(显示和隐藏)。被点击(我正在使用 Bootstrap )。 HTML: Advanced search This is t
我有两个 NSWindows,其中都有一个 NSPanel。我想在按下按钮时切换窗口。如何才能做到这一点?我不再需要旧窗口,所以我只想显示新窗口。 最佳答案 要聚焦第二个窗口,只需调用: [windo
我尝试在单击切换时将选项添加到选择菜单,但如果再次单击(取消选择),则可以将其删除。到目前为止,我可以在单击时向选择菜单添加单个值,但无法将其删除(切换添加切换删除) 这是我的代码: HTML
我正在尝试隐藏所属行。例如,如果您单击“子标题 1”,则将仅隐藏项目 1、项目 2 和项目 3 行。 示例: title Sub Title 1
似乎无法让它为我工作,任何人都可以为我提供帮助吗? http://codepen.io/anon/pen/kABjC 这应该根据点击打开和关闭文本部分,它采用 ID #,它只是一个数字(1,2,3,4
我正在从一个文件复制到另一个文件,并且我可以看到 Excel 在源文件和目标文件之间切换(如闪烁)。我希望宏从源复制并粘贴到目标,而不在文件之间切换(我不想闪烁)。 这里我得到了我的 Excel VB
我正在尝试制作一个带切换功能的 Accordion ,现在看起来效果很好。作为 javascript 的新手,我希望得到一些帮助,那就是它的组合方式。 http://jsfiddle.net/z3wW
我正在尝试制作一个小脚本,其中屏幕将每 100 毫秒随机更改一次背景颜色,您可以通过按一个按钮来打开和关闭它。我可以让它开始,但我不能让它停止。 这是切换的主要代码: var on = -1; fun
我确信这里应该已经涵盖了这一点,但我一直无法找到专门涉及此问题的问题。 我在一个页面中有 2 个 div,就像这样...... ...content... ...content...
我是一名优秀的程序员,十分优秀!