网络上Qt的中文相关的内容非常多,与之相应,
错误也相当多。为了使大家少走弯路,本文准备简单整理一下相关内容,但具体还没想好怎么写 ^_^
问题: 为何不建议使用中文?
如果你有追求简单或追求完美的癖好,源码内避免中文几乎是唯一选择。 由于
C++标准本身的对源
文件的编码
没有任何规定,使得各个
编译器对此可以随意发挥。故尔一旦使用了非ASCII的字符,可能会出现各种稀奇古怪的现象。尤其以MSVC对非ASCII编码的支持最为奇葩,完全一样的代码在不同语言的操作系统中可以得到完全不同的结果。
源码内使用ASCII代码,同时使用Qt提供的i18n方案,可以使得你的程序在不同环境下的行为都是正确的。
但如果你坚持使用中文,那么...
问题: UTF-8 还是 GBK ?
为了简化问题,我们此处不去区分C、C++中和中文密切相关的input-charset 和 exec-charset 这两个概念,暂且认为二者一致(如果你想彻底理清问题,区分二者却是必不可少的) - 如果你在使用VS2003,你应该使用 GBK ,且使用简体中文操作系统(你的代码在其他语言的系统下编译是有问题的)。
- 如果你在使用VS2005或VS2008,你只能使用 GBK,且使用简体中文操作系统
- 如果你在使用VS2010,尽管你仍可以使用GBK和简体中文操作系统,但最好选择 UTF-8(可跨各个语言)
- 如果你在使用GCC或Intel C++ 编译器或其他,首选 UTF-8
尽管从VS2010起,开始支持UTF-8,但是需要2个操作。
- 源码保存为 带 BOM 的UTF-8 (用以保证input-charset是UTF8)
- 源码开头添加如下代码 (用以保证exec-charset是UTF8)
- #if _MSC_VER >= 1600
- #pragma execution_character_set("utf-8")
- #endif
在Qt4下,我们可以告诉Qt我们使用的是何种字符集。可是,
问题: Qt5下如何选择?
从 Qt5.0开始,问题得到极大的简化,
你只能选择UTF-8作为执行字符集。同时,根据前面的分析,由于VS2005和VS2008无法使用UTF8作为执行字符集,故尔它们将无法用于这种场合!!
Qt4中的GBK那些用法不再有效,如果你仍要用GBK,请自行进行GBK编码的char* 到 Unicode的
QString的转化。
选择了编码并不是问题的结束,恰恰相反,它只是问题的开始
问题: setCodecForXxxxxx() 如何使用?
在Qt4时代,网络中充斥大量的setCodecForXxxxx的语句,但绝大多数的用法都是不规范的(或者说碰巧可以得到正确的结果)。 建议如下:
注意:
- tr() 是被滥用最多的函数之一,请不要纯粹为了中文乱码而使用它!
- 在Qt4中,请根据你所使用的是GBK还是UTF-8调用setCodecForCStrings()即可
- 在Qt5中,请确保你所使用的编码是UTF-8
- 不要使用codecForName("System")!!
比如,不少网友
在简体中文Windows下使用GBK时,会混用下面几个语句:
- QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
- QTextCodec::setCodecForCStrings(QTextCodec::codecForName("System"));
- QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
后者的问题是,在非简体中文系统下,程序乱码!所以,
不要使用后两个语句。
问题:为什么开发机上正常,发布时乱码?
如果同一个字符串中的字符,部分正常,部分
显示为方框或不显示。一般来说是字体问题,请
安装相应字体。
如果中文显示的乱码,而且你是在Qt4下使用的GBK编码,那么应该是你没有发布相应的GBK编解码插件。
* application.exe
*
codecs\qcncodecs4.dll
注意:一定要有那个codecs目录!!
问题:编译运行时,Qt自带对话框或控件为何显示英文?
Qt源码中的字符串都是英文,其国际化是通过程序加载相应的翻译文件来实现的。 翻译文件位于translations目录中
要让Qt内部的字符串正确显示中文,你必须安装Qt提供的你所需要的qm文件。代码片段如下:
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QTranslator *translator = new QTranslator(QCoreApplication::instance());
- if (translator->load("qt_zh_CN", YourDirPath)) {
- QCoreApplication::installTranslator(translator);
- ...
其中,YourDirPath可以用 QLibraryInfo::location(QLibraryInfo::TranslationsPath),也可以使用你自己喜欢的包含.qm文件的目录。
如果想让它根据locale加载不同语言的翻译文件,你也可以直接使用下列代码(该代码来自Qt Assistant的源码):
- void setupTranslation(const QString &fileName, const QString &dir)
- {
- QTranslator *translator = new QTranslator(QCoreApplication::instance());
- if (translator->load(fileName, dir)) {
- QCoreApplication::installTranslator(translator);
- } else if (!fileName.endsWith(QLatin1String("en_US")) && !fileName.endsWith(QLatin1String("_C"))) {
- qWarning("Could not load translation file %s in directory %s.", qPrintable(fileName), qPrintable(dir));
- }
- }
- void setupTranslations()
- {
- const QString& locale = QLocale::system().name();
- const QString &resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath); //假定所有翻译文件在Qt的标准翻译目录下
- setupTranslation(QLatin1String("yourself_") + locale, resourceDir);
- setupTranslation(QLatin1String("qt_") + locale, resourceDir);
- setupTranslation(QLatin1String("qt_help_") + locale, resourceDir);
- }
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- setupTranslations();
- ...
问题:发布时,Qt自带的对话框或Assistant等工具为何是英文?
仅仅代码中有相应的加载代码还是不够的,程序发布时,你需要发布你所需要的所有 .qm 文件,并且需要让你的程序能够找到他们。
情况一:代码中使用完全自定义目录,比如说,放置于可执行程序所在目录 QCoreApplication::applicationDirPath() 下的某个文件夹。这个没什么好说的。
情况二:使用标准目录 QLibraryInfo::location(QLibraryInfo::TranslationsPath)。在开发程序的机器上,它就是Qt下面的translations目录。可是发布程序是,这些 .qm 该放置于何处呢??
答案:我们可以随意放置,只需要通过创建一个 qt.conf 文件,在该文件内指定一下目录即可。比如
- [Paths]
- Prefix=.
- Translations = translations
问题: ? 问题: ? 问题: ? 问题: ? 推荐相关文章
关于Qt4程序支持中文方法的总结 QString 乱谈(2)-C++中的中文