qt输出中文乱码解决方法,qt5输出中文乱码
分类:IDE使用技术2009-09-21 21:44 5661人阅读评论(2)收集并报告qt中文乱码初学Linux,直接进阶QT编程。然而第一个演示程序就遇到了中文乱码,汗!环境:
1、RedHat AS5
2、QT4.4.0
3、郎=zh_CN。GB18030
程序:
.
QTextCodec:setCodecForTr(QTextCodec:codecForName( GB 18030 );
.
Label.setText(QObject:tr(同一个世界,同一个梦想!));
.
结果:
标题显示正常,标签和按钮汉字乱码。
网上搜索3 ~ 4天,总结如下:
1.使用setDefaultCodec进行设置;
qApp-setDefaultCodec(QTextCodec:codecForName( GBK ));
QLabel *label=new QLabel( tr(中文标签);
不幸的是,setDefaultCodec是QT3的一个功能,QT4不再支持它。
2.设置QObject的成员函数tr()的编码;
QTextCodec:setCodecForTr(QTextCodec:codecForName( GBK ));
3.使用QString的fromLocal8Bit()函数;
QString字符串;
Str=str.fromLocal8Bit(哈哈哈);
hello . setwindowtitle(str);
4.使用QTextCodec的toUnicode方法显示中文。
QLabel Hello(q object:tr:tr( Hello )。tolocal 8 bit());
QTextCodec * codec=QTextCodec:codecForLocale();
QString a=codec- toUnicode(安仕达手册);
以上都没有解决问题。
我没有继续搜索这个问题,最后在一个博客里找到了真正的答案:字体问题。
在QT4下发现一个奇怪的现象,就是对话框标题“我是对话框”可以正确显示,按钮是一个小方块。总感觉系统有些设置不对,不是字符编码的问题。如果是字符编码的问题,那么应该是乱码而不是小方块。突然想到网上提到字体的问题,觉得现象可以解释。标题栏和按钮文字不是同一种字体,只是按钮字体不存在,所以是小方块,不是乱码。
我在网上搜索了QT4使用的默认字体,没有找到。我也看了QT4的源代码,但是代码太多,找不到。
但是setFont函数引起了我的注意,我在网上看到过这个方法。"
参考上述内容并修改代码:
.
QTextCodec:setCodecForTr(QTextCodec:codecForName( GB 18030 );
QFont font(Times ,12,QFont:Normal,FALSE);
app.setFont(字体);
.
Label.setText(QObject:tr(同一个世界,同一个梦想!));
.
成功!中文显示正常!
解决这个问题太重要了。说实话,我真的很累,但还好我没有放弃。耶!
后记:使用qt designer时,发现界面还是乱码。使用qtconfig将字体设置为比特流Charter,解决乱码问题。至此,不知原程序是否可以?没想到居然没有乱码~ ohmygod!
来自:http://www . linuxdiyf . com/view article . PHP?id=97025
其他解决方案:
Qtext Codec: Codecforname ("GBK ")将返回一个空指针。
QTextCodec * BianMa=QTextCodec:codecForLocale();//QTextCodec:codec forname( GBK );
Qt中的中文显示集合可以通过QText codec直接转换字符串的编码,为在QT下开发中文软件带来了方便,但是这种方法不符合国际/地方标准:
代码:
Char *string= Hello world!;
QTextCodec * codec=QTextCodec:codecForName( GBK );
//QTextCodec * codec=QTextCodec:codecForName( big 5 );
QString strText=codec-toUnicode(string);
q label * label=new q label(strText);
最直接的方法是将整个应用程序的编码设置为GBK编码,然后在字符串前加上tr:
代码:
qApp-setDefaultCodec(QTextCodec:codecForName( GBK ));
.
QLabel * label=new QLabel(tr( Hello,world!));
示例:
代码:
#包括
#include#include qtextcodec.h //文件头
int main( int argc,char *argv[])
{
QApplication app( argc,argv);
app . setdefaultcodec(QTextCodec:codecForName( GBK ));
QLabel label(tr (Hello,world!),NULL);
app.setMainWidget(标签);
label . show();
返回app . exec();
}
如果QT根据Locale的环境变量获取字符集,您可以使用以下命令:
QString:fromLocal8Bit (Hello,world!);
示例:
代码:
#包括
#包括
int main( int argc,char *argv[])
{
QApplication app( argc,argv);
QLabel(QString:from local 8 bit( Hello,world!),NULL);
app.setMainWidget(标签);
label . show();
返回app . exec();
} -
方法二:
QTextCodec:setCodecForTr(QTextCodec:codecForLocale());- .
QString init_gbk(QString s)
{
QGbkCodec * gbk=(QGbkCodec *)QTextCodec:codec forname(/ GBK/);
返回gbk- toUnicode(s.latin1(),s . length());
}
只需调用QT中文文件
学点东西才是正道,2008-08-23 17:00阅读85条评论0字号:大中小虽然C标准中有文件阅读的相关类,也很好用,但是到了QT编程的时候就不方便用了,因为QT本身的很多组件都是自己QString类型的字符串,因此,使用C本身的字符串类型就不是那么方便了,需要转换,带来了程序的复杂性和转换的开销。所以如果用QT进行开发,可以和这些类型的C本身进行处理,形成一个系统,方便程序之间的数据交互和共享。
QT很好,但是在处理中文或者其他语言的时候,要注意编码格式。如果你不注意,当你读一个文件的时候,你可能会读到乱码或者程序会直接死掉。这是我们不愿意看到的。下面介绍如何通过QT的类读取中文文件。
导言部分
我们需要使用几个头文件中的类:
#包含qstring.h
#include qfile.h
#包含qtextstream.h
#包含qtextcodec.h
转
QString类提供了Unicode文本和以零结尾的经典C字符数组的抽象。
QString使用隐式共享,这使得它非常高效且易于使用。
所有QString方法都使用const char *参数,const char *被解释为以零结尾的经典C风格ASCII字符串。所以const char *参数为0是合法的。如果const char *不以零结尾,那么结果是不确定的。将经典C字符串复制到QString的函数不会复制结尾的0字符。QString的QChar数组(可以用unicode()返回)通常不以零结尾。如果你需要将QString传递给一个需要C的以零结尾的字符串,请使用latin1()。
不分配任何内容的QString为零,即长度和数据指针都为零。引用空字符串(",单个/0 字符)的QString为空。两个QString,zero和null,在方法中是合法的。将(const char *) 0赋给QString会得到一个零QString。为了方便起见,QString:null是一个零QString。排序时,先空字符串,然后非空字符串,最后零字符串。我们建议使用if(!Str.isNull())而不是if(!Str)来检测非零字符串。有关说明,请咨询操作员!()。
注意,如果你发现你在混合使用QCString、QString和QByteArray,这将导致大量不必要的重复,并可能表明你正在处理的真实自我数据是不确定的。如果数据是以零结尾的八位数据,请使用QCString;如果它没有结尾(即包含0)的八位字节数据,请使用QByteArray;如果是文本,请使用QString。
可以使用QStringList类处理该列表。可以使用QStringList:split()将一个字符串拆分成一个字符串列表,还可以使用QStringList:join()将一个字符串列表连接成一个带有任意分隔符的字符串。还可以使用QStringList:grep()从字符串列表中获取包含特定子字符串或匹配特定正则表达式的字符串列表。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QFile
QFile class q是一个用于操作文件的输入/输出设备。
QFile是一个输入/输出设备,用于读写二进制文件和文本文件。QFile可以单独使用,但是如果配合QDataStream或者QTextStream使用会更方便。
文件名通常可以通过构造函数传递,但也可以使用setName()设置。可以通过exists()检查文件是否存在,通过remove()删除文件。
文件可以用open()打开,用close()关闭,用flush()刷新。一般来说,可以使用QDataStream或QTextStream来读写数据,但是也可以使用readBlock()和readLine()来读取数据,使用writeBlock()来写入数据。QFile还支持getch()、ungetch()和putch()。
Size()可以返回文件的大小。您可以使用at()函数获取当前文件位置或移动到新的文件位置。如果到达文件末尾,AtEnd()返回true。Handle()返回文件句柄。
下面是使用QTextStream逐行读取文本文件的代码片段。它将打印出带有行号的每一行。
QStringList行;
QFile文件( file . txt );
if ( file.open( IO_ReadOnly ) ) {
QTextStream流(文件);
QString线;
int n=1;
而(!stream.eof() ) {
line=stream . readline();//一行文本,不包括“/n”
printf( =: %s/n ,n,line . latin1());
线条=线条;
}
file . close();
}
编写文本也很容易(假设我们有一个要编写的字符串列表):
QFile文件( file . txt );
if ( file.open( IO_WriteOnly ) ) {
QTextStream流(文件);
for(QStringList:Iterator it=lines . begin();它!=lines . end();它)
stream * it /n ;
file . close();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QTextStream
QTextStream类提供了使用QIODevice读写文本的基本功能。
text类的函数接口和c的标准iostream类很像,iostream和QTextStream的区别在于,我们的流是在一个很容易继承的QIODevice上操作的,而iostream只能在一个不能继承的FILE *指针上操作。
Qt提供了几个类似于iostream的全局函数:
将QTextStream设置为读/写二进制数。
将QTextStream设置为读/写八进制数。
将dec的QTextStream设置为读/写十进制数。
将QTextStream设置为读/写十六进制数。
Endl强制换行
强制QIODevice刷新所有缓存的数据。
Ws作为任何可用的控制字符(在输入时)
Reset将QTextStream设置为默认模式(参见reset())
QSetW(int)将字段宽度设置为指定的参数。
QSetFill(int)将填充字符设置为指定的参数。
QSetPrecision(int)将精度设置为指定的参数。
警告:默认情况下,QTextStream在读取流时会自动检测流中的数字是十进制、八进制、十六进制还是二进制格式。具体来说,以“0”开头的数字是八进制的,例如,序列“0100”将被解释为64。
QTextStream类读写文本,它不适合处理二进制数据(而QDataStream适合)。
默认情况下,输出是用本地8位编码的Unicode文本(例如QString)。这些可以使用setEncoding()方法进行更改。对于输入,QTextStream将自动检测标准的Unicode“字节顺序标记”文本文件,否则它将使用本地8位编码。
QIODevice是在构造函数中设置的,或者稍后在setDevice()中使用。如果输入达到atEnd(),则返回true。可以使用operator()重载运算符将数据读入适当类型的变量,或者使用read()将数据作为整个部分读入单个字符串,或者使用readLine()一次读取一行。使用skipWhiteSpace()忽略控制字符。您可以使用flags()或setf()来设置流的标志。此流还支持width()、precision()和fill()。使用reset()恢复默认设置。
也可以参考QDataStream,输入/输出,网络和文本相关类。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
问题
QTextCodec类提供文本编码之间的转换。
QT Unicode用于存储、绘制和操作字符串。在许多情况下,您可能希望使用不同的编码方法来处理数据。例如,大多数日语文件存储在Shift-JIS或ISO2022文件中,而俄罗斯用户通常使用KOI8-R或CP1251编码。QT提供了一个QTextCodec类的集合,用于从Unicode格式转换成相应的格式。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
代码部分
#包含qstring.h
#include qfile.h
#包含qtextstream.h
#包含qtextcodec.h
int main()
{
QFile文件(“test . txt”);
if(file . open(IO _ ReadOnly IO _ Raw))
{
QTextStream floStream(文件);
QString线;
QTextCodec * codec=QTextCodec:codecForName( GBK );
floStream.setCodec(编解码器);
while ( floStream.atEnd()==0)
{
line=codec-from unicode(flostream . readline());
qWarning(行);
}
file . close();
}
返回0;
}
代码中的主要变化是黄色背景。
意思是创建一个中文GBK编码样式,然后通过这种方式对读取的文件流进行重新编码,这样就可以流畅地输出中文了。不信你可以试试。
就编这两句,显示中文。
#包含qtextcodec.h
QTextCodec:setCodecForTr(QTextCodec:codecForName( GB 2312 ));
说说Qt的中文编码~来源:ChinaUnix博客日期:2009.07.04 11:23(共1条评论)我要评论。
原始链接:
http://www.cuteqt.com/blog/?p=531
为什么我的中文显示不出来?在Qt的使用中,朋友们经常会遇到这样的问题。
通过谷歌搜索,你会发现已经有人解决了,无非就是重置默认编码器。
首先调用以下两个函数之一
QTextCodec * textc=QTextCodec:codecForName(" gbk ");
QTextCodec * textc=QTextCodec:codec forname(" utf8 ");
然后调用以下三个函数之一。
QTextCodec:setcodecforstrings(textc);
QTextCodec:setCodecForTr(textc);
QTextCodec:setCodecForLocale(textc);
至于叫哪个,我也不知道,只好挨着试了。反正组合不多。问题解决了。但是下次再试一次。
让我们来看看这些函数在哪里工作。
1.setcodecforstrings(textc)
这个函数主要使用在用字符常量或QByteArray构造QString对象时使用的默认编码方法。例如,下面的例子
23 int main(int argc,char *argv[]){
24 QApplication app(argc,argv);
25
26 QTextCodec * TC=QTextCodec:codec forname(" utf8 ");
27 QTextCodec:setcodecforstrings(TC);
28 QString str("我宁愿看两个恶魔拔河,也不愿看天使跳舞。");
29按钮ww(str);
30 ww . show();
31
32 app . exec();
33 }
如果您注释掉第26行和第27行,那么我们在QPushButton上看到的将是一堆乱码。因为默认情况下,QString将构造函数的字符串参数作为标准的拉丁字符,很明显会出现乱码。如果是在Linux下,当您在编辑器中输入时,默认的文本格式是“utf8”。如果是在windows下开发,26行的地方大概就要改成“gbk”了。
2.setCodecForTr(textc)
该函数用于设置传递给tr函数时的默认字符串编码。
23 int main(int argc,char *argv[]){
24 QApplication app(argc,argv);
25
26 QTextCodec * TC=QTextCodec:codec forname(" utf8 ");
27 QTextCodec:setcodecforstrings(TC);
28 QString str(QObject:tr)“我宁愿看两个恶魔拔河,也不愿看一个天使跳舞。”));
29按钮ww(str);
30 ww . show();
31
32 app . exec();
33 }
同样的例子,我在第28行添加tr后,运行结果又不能正常显示中文了。只需将27行函数改为setCodecForTr即可。
3.QTextCodec:setCodecForLocale(textc)
该函数主要用于设置读写本地文件系统时的默认编码格式。例如,通过流读取文件时内容的编码格式。或者打印信息时的代码是通过qDebug()输出的。
7 int main(int argc,char *argv[]){
8 QTextCodec * TC=QTextCodec:codec forname(" utf8 ");
9 QTextCodec:setcodecforstrings(TC);
1QString str("我宁愿看两个恶魔拔河,也不愿看天使跳舞。");
11
12 QTextCodec * TL=QTextCodec:codec forname(" utf8 ");
13 QTextCodec:setCodecForLocale(TL);
14 qDebug()
ANSI、Unicode、UTF8字符串之间的转换以及写入文本文件。出自:http://www.blogjava.net/Yipak/articles/227015.htmlAnsi弦乐是我们最熟悉的。英语占一个字节,汉字有两个字节,以/0结尾,常用于txt文本文件。
Unicode字符串,每个字符(汉字、英文字母)占用2个字节,以2个连续的/0结尾。该字符串由NT操作系统内核使用,通常定义为typedef无符号短wchar _ t;所以有时候我们经常会看到一些错误比如char*不能转换成无符号short*,其实就是unicode。
Utf8是unicode的压缩形式,英语A用Unicode表示为0x0041。外国人觉得这种存储方式太浪费了,因为浪费了50%的空间,所以把英语压缩成一个字节,就成了utf8编码。但是汉字用utf8占三个字节,显然不如ansi划算。这就是为什么中国的网页都用ansi码,而外国人的网页经常用UTF8。
UTF8在回归游戏中被广泛使用,比如WOW的lua脚本。
先说转换,主要用代码来解释。
我用CFile类写文件。其实FILE*之类的也是一样。写文件和字符串的类别无关。硬件只关心数据和长度。
Ansi到Unicode
介绍两种方法。
void CConvertDlg:OnBnClickedButtonAnsiToUnicode()
{
//ansitounicode
Char * szAnsi= abcd1234你我他;
//预转换以获得所需空间的大小
int wcs len=:MultiByteToWideChar(CP _ ACP,NULL,szAnsi,strlen(szAnsi),NULL,0);
//分配空间为“/0”腾出空间,但MultiByteToWideChar不会为“/0”腾出空间
wchar _ t * wsz string=new wchar _ t[wcs len 1];
//转换
* MultiByteToWideChar(CP _ ACP,NULL,szAnsi,strlen(szAnsi),wszString,wcs len);
//在末尾添加“/0”
wsz string[wcs len]=/0 ;
//unicode版本的MessageBoxAPI
* MessageBoxW(GetSafeHwnd()、wszString、wszString、MB _ OK);
//接下来写入文本
//写入一个文本文件,首先写入前2个字节0xfeff和低位0xff。
CFilecFile
cFile。Open(_T( 1.txt ),CFile:mode write CFile:mode create);
//文件的开头
cFile。SeekToBegin();
cFile。写(/xff/xfe ,2);
//写内容
cFile。Write(wszString,wcs len * sizeof(wchar _ t));
cFile。flush();
cFile。close();
删除[]wsz string;
wszString=NULL
//方法2
//设置当前区域信息。如果未设置,使用此方法将无法正确显示中文。
//需要# includeLocale.h。
setlocale(LC_CTYPE, CHS );
wchar _ twcsStr[100];
//请注意,下面是一个大写的S,在unicode中,该代表后跟一个ansi字符串
//swprintf是sprintf的unicode版本。
//格式前面写L,表示unicode。
swprintf(wcsStr,L %S ,SZ ansi);
* messagebox w(GetSafeHwnd()、wcsStr、wcsStr、MB _ OK);
}
Unicode到Ansi
也有两种方法。
void CConvertDlg:OnBnClickedButtonUnicodeToAnsi()
{
//unicodetoansi
Wchar_t * wszString=L abcd1234你我他;
//预转换以获得所需空间的大小。这次用的函数和上面的名字相反。
int ansiLen=:WideCharToMultiByte(CP _ ACP,NULL,wszString,wcslen(wszString),NULL,0,NULL,NULL);
//同上,分配空间给“/0”留一个空间
char * SZ ansi=new char[ansi len 1];
//转换
Unicode版本对应的strlen是wcslen
* WideCharToMultiByte(CP _ ACP,NULL,wszString,wcslen(wszString),szAnsi,ansiLen,NULL,NULL);
//在末尾添加“/0”
SZ ansi[ansiLen]=/0 ;
//Ansi版本的MessageBoxAPI
* messagebox(getsafehwnd()、szAnsi、szAnsi、MB _ OK);
//接下来写入文本
//写文本文件,ANSI文件没有很好
cfile文件
-你好. Open(_T( 1.txt ),cfile:mode write cfile:mode create;
//文件开头
-你好seekttobegin();
//写入内容
-你好Write(szAnsi、ansi * sizeof(char));
-你好flush();
-你好. close();
删除[]SZ ansi;
szAnsi=NULL:
//方法2
//和上面一样有另一种方法
setlocale(LC_CTYPE, chs ):
char SZ str[100];
//注意下面是大写,在美国国家标准学会标准中,代表后面是统一码(unicode)字符串
//冲刺(短跑)
sprint(SZ str,“%S”,wszstring);
* messagebox(getsafehwnd()、sztr、sztr、MB_OK):
}
统一码(unicode)转UTF8表示
请参阅ccconverttdlg:onnckedbutton unicode tou 8()
{
//unicodetoUTF8
wchar _ t * wszsstring=ABCD 1234你我他";
//预转换,得到所需空间的大小,这次用的函数和上面名字相反
int u8 len=:widchartommultibyte(CP _ utf8、NULL、wszstring、wcs len(wszstring)、NULL、0、NULL、NULL);
//同上,分配空间要给/0 留个空间
//UTF8虽然是统一码(unicode)的压缩形式,但也是多字节字符串,所以可以以char(字符)的形式保存
char * us8=新char[u8len 1];
//转换
//unicode版对应的斯特伦是wcslen先生
* widchartombyte(CP _ utf8、NULL、wszstring、wcs len(wszstring)、us8、u8Len、NULL、NULL);
//最后加上/0
S7-1200可编程控制器:
//MessageBox不支持UTF8表示,所以只能写文件
//接下来写入文本
//写文本文件,UTF8的很好是0xbfbbef
cfile文件
-你好. Open(_T( 1.txt ),cfile:mode write cfile:mode create;
//文件开头
-你好seekttobegin();
//写好吧,同样低位写在前
-你好。写入(/xef/xbb/xbf ,3);
//写入内容
-你好. write(us8、u8 len * sizeof(char));
-你好flush();
-你好. close();
删除[]su8;
us8=零;
}
UTF8表示转统一码(unicode)
请参见ccconverttdlg:onncickedbutton 8 to nicode()
{
//UTF8toUnicode
//由于中文直接复制过来会成乱码,编译器有时会报错,故采用16进制形式
char * us8= ABCD 1234/xe 4/xbd/xa 0/xe 6/88x 91/xe 4/xbb/x96/x00 ;
//预转换,得到所需空间的大小
int wcsLen=:多重位元组ToWideChar(CP_UTF8、NULL、us8、strlen(us8)、NULL、0);
//分配空间要给/0 留个空间,多字节转储不会给/0 空间
wchar _ t * wszstring=新wchar _ t[wcs len 1];
//转换
*多字节towidechar(CP _ utf8、NULL、us8、strlen(us8)、wszstring、wcs len);
//最后加上/0
S7-1200可编程控制器:
//unicode版的MessageBoxAPI
* messagebox w(getsafehwnd()、wszstring、wszstring、MB_OK):
//写文本同焦虑不安
} Ansi转换utf8表示和utf8表示转换美国国家标准学会标准就是上面2个的结合,把统一码(unicode)作为中间量,进行2次转换即可