文号
t80033
阅读
10624
回复
7
收藏
3
Qt中使用中文的方法
2016/05/28
IP:四川
首先,不要使用tr,tr是编写国际化程序才需要的。tr包裹住的是英文,可提供翻译包翻译成中文,大多数情况来说是不必要的。
其次,不要使用QTextCodec::setCodecForXXX,这个在Qt5已经被废除了,在Qt4中如果设置为"GBK",对Win98也不起作用,最好是设置成"UTF-8"。

正确的做法是使用QString::fromWCharArray。为了方便起见,可以定义一个宏:
#define _Q(x) QString::fromWCharArray(L##x)
这个宏在Win98、WinNT和Linux中都能够正常工作,不会乱码。

示例代码如下:
#include <qapplication>
#include <qfont>
#include <qpushbutton>
#include <qtcore qtextcodec>
#include <string.h>
   
#define _Q(x) QString::fromWCharArray(L##x)
   
int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
   
    QWidget window;
    window.resize(200, 120);
   
    QPushButton quit(_Q("我是中文"), &window);
    quit.setFont(QFont("SimSun", 18, QFont::Bold));
    quit.setGeometry(10, 40, 180, 40);
    QObject::connect(&quit, SIGNAL(clicked()), &app, SLOT(quit()));
   
    window.show();
    return app.exec();
}</string.h></qtcore></qpushbutton></qfont></qapplication>
[ 修改于10年6个月前 - 2016/05/28 12:47:11 ]
acmilan作者
10年6个月前修改于 10年6个月前IP:四川
820200
1楼
编写中文软件,使用_Q(x)宏就行了,如果需要编写国际化软件,再使用tr(x)宏。。。
这样的话,在Win98/WinNT中执行时只会进行字符串拷贝,而在Linux执行时会进行一次UTF-32到UTF-16的转换(因为Linux中的wchar_t是UTF-32)。
引用
评论
acmilan作者
10年6个月前IP:四川
820205
2楼
如果需要调用WinAPI的话,建议另外建立一个适当编码的*.cpp文件来调用WinAPI。。。
1.windows.h会和Qt的头文件冲突
2.MinGW解析wchar_t字符串常量要求源代码是UTF-8,而这样的话会导致char字符串常量乱码
如果需要调用宽字符版本WinAPI,使用UTF-8编码保存源码
如果需要调用ANSI版本的WinAPI,使用GBK编码保存源码
引用
评论
10年6个月前IP:浙江
820207
3楼
我都是用tr或者QString
引用
评论
acmilan作者
10年6个月前IP:四川
820208
4楼
引用 .........:
我都是用tr或者QString
Qt4一个很坑的地方就是英语中心主义,char字符串就是设计为仅兼容英语Latin1的。。。
这个问题在Qt5中改掉了,Qt5中编码默认就给你设好了,所以直接用就可以了。。。
Qt5默认和系统区域相同,比如Windows下是GBK,Linux下是UTF-8。。。
Qt5中也没必要关心Win98的问题,因为本来就不支持了。。。
引用
评论
acmilan作者
10年6个月前IP:四川
820209
5楼
嗯。。。如果要在Qt4中同时实现翻译和中文显示,可以这样定义_Q(x):
#define _Q(x) trUtf8(QString::fromWCharArray(L##x).toUtf8().data())
虽然麻烦了点,但是这是可移植性最好的做法。。。(注意要加上BOM)
引用
评论
acmilan作者
10年6个月前IP:四川
820485
6楼
如果需要同时调用ANSI和Unicode宽字符版本的WinAPI的话,也可以使用-finput-charset=GBK参数实现
但是仍然需要在单独的文件中调用,不然windows.h和Qt的头文件会冲突
引用
评论
10年6个月前IP:河北
820574
7楼
其实正确的姿势应该是先编写英文版本,然后进行国际化
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的