• 彻底解决QT编码问题


    彻底解决QT编码问题

    字符串常量、"中文"是传统的char类型的窄字符串、在使用的时候只需要告诉QString这两个汉字采用的编码构造QString。

    const char * str = "中文";
    QString qstr = str;   //相当于调用QString::QString(const char * str)初始化一个QString
    

    概念1:源文件是有编码的
    "中文" 在不同的编码下对应不同的二进制形式
    可能在GBK编码下是:ce d2 ca c7
    在Latin-1编码下是:ba ba d7 d6

    概念2:QString内部采用的是Unicode

    一个问题,源代码中假如有4个字节"xcexd2xcaxc7“该怎么转换成Unicode并存储在QString内。按照GBK、BIG5、Latin-1还是其他方式...
    在你不告诉它的情况下,它默认选择了Latin-1,于是4个字符"ÎÒÊÇ"的unicode码被存进了QString中。最终,4个Latin字符出现在你期盼看到2中文字符的地方,所谓的乱码出现了

    解决方式

    问题很简单,当你需要从窄字符串 char* 转成Unicode的QString字符串的,你需要告诉QString你的这串char* 中究竟是什么编码?GBK、BIG5、Latin-1
    理想情况就是:将char* 传给QString时,同时告诉QString自己的编码是什么

    就像下面的函数一样,QString的成员函数知道按照何种编码来处理 C 字符串
    QString QString::fromAscii ( const char * str, int size = -1 )
    QString QString::fromLatin1 ( const char * str, int size = -1 ) 
    QString QString::fromLocal8Bit ( const char * str, int size = -1 )
    QString QString::fromUtf8 ( const char * str, int size = -1 )
    QString 只提供了这几个成员函数,远远满足不了大家的需求,比如,在简体中文Windows下,local8Bit是GBK,可是有一个char串是 BIG5 或 Latin-2怎么办?
    
    可以使用强大的QTextCodec,首先QTextCodec肯定知道自己所负责的编码的,当你把一个char串送给它,就能正确将其转成Unicode
    QString QTextCodec::toUnicode ( const char * chars ) const
    
    可是这个调用太麻烦了
    想直接
    QString a= str;
    QString a(str);
    
    这样一来肯定没办法同时告诉 QString 你的str是何种编码了,只能通过其他方式了。
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    设置QString默认采用的编码。而究竟采用哪一个,一般来说就是源代码是GBK,就用GBK,源代码是UTF-8就用UTF-8。但有一个例外,如果你保存成了带BOM的UTF-8而且用的微软的cl编译器,此时仍是GBK。
    

    总结

    QString内部采用的是 Unicode,它可以同时存放GBK中的字符"我是汉字",BIG5中的字符"扂岆犖趼" 以及Latin-1中的字符"ÎÒÊǺº×Ö"。

    当你需要从窄字符串 char* 转成Unicode的QString字符串的,你需要告诉QString你的这串char* 中究竟是什么编码?GBK、BIG5、Latin-1?

    在你不告诉它的情况下,它默认选择了Latin-1,于是8个字符"ÎÒÊǺº×Ö"的unicode码被存进了QString中。最终,8个Latin字符出现在你期盼看到4中文字符的地方,

    所谓的乱码出现了。

    网上有很多方法介绍直接在main.cpp里设置:

    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForTr(codec);
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    

    其实这在某些情况下也是有问题的,因为程序可能读到系统的中文路径,或者调用中文路径下的外部程序,这时候如果系统是gb2312就有问题了。

    因为中文路径的编码是采用utf-8存到QString里的,系统读中文路径解码的时候采用的却是系统的gb2312,所以会调不起带中文路径的外部程序。

    以上问题下面方法可以解决:

    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForTr(codec);
    QTextCodec::setCodecForLocale(QTextCodec::codecForLocale()); //设置GBK到本地
    QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
    

    对于外部字符串编码解码全部采用本地编码。

    在QT5中,加上这句,源文件使用UTF-8编码,不带BOM
    QApplication a(argc, argv);
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
  • 相关阅读:
    Linux根目录各个文件夹介绍及说明
    CentOS7 yum方式安装MySQL5.7
    spring-boot 启动图标修改-启动彩蛋
    Android 4.4从图库选择图片,获取图片路径并裁剪
    Android开发之获取相册照片和获取拍照照片二
    Android开发之获取相册照片和获取拍照照片
    httpclient 发送文件和字符串信息
    HttpURLConnection 发送 文件和字符串信息
    Android中使用HTTP服务
    android http json请求3种不同写法
  • 原文地址:https://www.cnblogs.com/liunian1004/p/5912536.html
Copyright © 2020-2023  润新知