QT下面的中文乱码问题

 字符编码问题详解:   http://blog.csdn.net/bluetjs/article/details/52936943

http://blog.csdn.net/u010737354/article/details/52456570
http://www.360doc.com/content/12/0423/17/9470897_205933736.shtml
http://www.bangnishouji.com/tools/chtounicode.html
http://www.2cto.com/kf/201604/503757.html

下面是对上面网址的试验理解:

QT下面的中文乱码问题_第1张图片

使用UNICODE字符集:
int t1=sizeof(TCHAR);  2
int t2=sizeof(CHAR); 1
使用多字节字符集:
int t1=sizeof(TCHAR);  1
int t2=sizeof(CHAR); 1
未设置:
int t1=sizeof(TCHAR);  1
int t2=sizeof(CHAR); 1
从父级或项目默认设置继承:
int t1=sizeof(TCHAR);  1
int t2=sizeof(CHAR); 1

以 CreateFile 为例 不同的字符集设置,要使用不同的函数 : 不同函数处理方式不一样 有些是这样,有些不是这样
#ifdef UNICODE  // 相等于 设置中勾选 使用UNICODE字符集:
#define CreateFile  CreateFileW
#else
#define CreateFile  CreateFileA
#endif // !UNICODE

CreateFileW(

    __in     LPCWSTR lpFileName,
    __in     DWORD dwDesiredAccess,
    __in     DWORD dwShareMode,
    __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    __in     DWORD dwCreationDisposition,
    __in     DWORD dwFlagsAndAttributes,
    __in_opt HANDLE hTemplateFile
    );

CreateFileA(
    __in     LPCSTR lpFileName,
    __in     DWORD dwDesiredAccess,
    __in     DWORD dwShareMode,
    __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    __in     DWORD dwCreationDisposition,
    __in     DWORD dwFlagsAndAttributes,
    __in_opt HANDLE hTemplateFile
    );
比较 CreateFileW CreateFileA 发现 第一个参数 lpFileName, 的类型不一样,LPCWSTR  LPCSTR  可见编码格式对它的影响。

QT下面的中文乱码问题_第2张图片因为我是下面联调,我把数据 透传给下层,后来直接用的 std::string QString::toStdString()  ,在QT中中文显示 是乱码,但是在下层中文可以正常显示,所以,如果 你的代码是联调,一定要先测试一下,再决定 哈,不然你转半天,发现透传到下层程序 又好了!!!

参考 
http://blog.csdn.net/libaineu2004/article/details/19245205

http://blog.csdn.net/brave_heart_lxl/article/details/7186631
后来上面2个帖子里面的内容都没有用上,不过 还是要谢谢他们 !!!   
下面是我自己的解决方案: 
QJsonValue name_value = obj.take(QObject::tr("serviceCNName"));
            if(name_value.isString())
            {
QString strTT;
                strTT = name_value.toString(QObject::tr(""));;//中文非乱码 内容为  测试中文代码  ,共6个汉字   ----  解决方案 
int lent5=strTT.length();//6  
serviceCNName=strTT.toStdString();//乱码      
int lent6=serviceCNName.length();//18   
QByteArray ba = strTT.toLocal8Bit();//中文非乱码      ----  解决方案 
int lent7=ba.length();//12
                serviceCNName=ba.toStdString();//中文非乱码   ---  解决方案 
int lent8=serviceCNName.length();//12
                const QChar * p2= strTT.unicode() ;


QString strt1;
strt1.append(p2, strTT.length());//中文非乱码
int lent9=strt1.length();//6
//test code b
                QByteArray ba8=strTT.toUtf8();//乱码
int lent10=ba8.length();//18
string str8=ba8.toStdString();//乱码
int lent11=str8.length();//18
std::wstring wstr8=strTT.toStdWString();//中文非乱码
int lent12=wstr8.length();//6
std::string str8std=strTT.toStdString();//乱码
int lent13=str8std.length();//18
                //std::u16string str16=QString::toStdU16String();
                const QChar * p1= strTT.unicode();
int lent1=strTT.length();//6
QString strt2=strTT.setUnicode(p1, lent1);//中文非乱码
int lent2=strt2.length();//6
string sstrt1=strt2.toStdString();//乱码
int lent3=sstrt1.length();//18
                wstring sstrt2=strt2.toStdWString();//中文非乱码
int lent4=sstrt2.length();//6
//test code e




//serviceClassStr=name_value.toString(QObject::tr(""));
//QString::toLocal8Bit()
//serviceClass=ba.toStdString();
                //serviceCNName=strTT.toStdWString() ;
            }
下面贴一段WSTR转换为单STR 的代码:以供以后遇到 这样的问题时的参考:
void W2C(const wchar_t *pw , char *pc)
{
    *pc++ = (*pw)& 0xFF;
    *pc = (*pw)>>8;
}


char *wstr2cstr(const wchar_t *pwstr , char *pcstr)
{
    char *ptemp = pcstr ;
    if(pwstr!=NULL && pcstr!=NULL)
    {
        size_t wstr_len = wcslen(pwstr) ;
        while( wstr_len -- > 0)
        {
            W2C(pwstr , pcstr);
            pwstr++ ;
            pcstr +=2 ;
        }
        *pcstr = '\0';
        return ptemp ;
    }
    return 0 ;
}
附录:我目前是在QT551 里面用,后台 用的是JAVA和C++程序 ,JAVA过来的数据包是JSON格式的,是UNICODE编码,C++下面是标准的string函数,在所有的数据接口中,不建议用QString,因为它会在不同的QT版本中有不同的函数,所以外部数据接口一律用标准的string,另外,这只是 在WINDOWS下面的调试通过 ,LINUX下面这些QT代码还没有调试。等LINUX调试了再说明LINUX的代码说明,须知。
把代码保存方式存储为 UTF-8,下面是代码:
QString testQstring1=QString::fromLocal8Bit("系统服务");
QString testQstring2=QString::fromLocal8Bit("系统服务"); --- 中文可以正确显示
int len1=testQstring1.length();
string s1=testQstring1.toStdString();
int len2=s1.length();
QByteArray ba=testQstring1.toLocal8Bit();
int len3=ba.length();
int c1=testQstring1.compare(tr("系统服务"));  -- 不相等
int c2=testQstring1.compare(testQstring2);    -- 相等
参见 QTextCodec 例子地址:
QTextCodec 例子: E:\Qt\Qt5.5.1\Examples\Qt-5.5\widgets\tools\codecs\codecs.pro
可以把此例子运行起来,自己写些中文上去,看看不同的编码出来是什么结果


"UTF-8"     106
"ISO-8859-1"     4
"ISO-8859-15"     111
"UTF-32LE"     1019
"UTF-32BE"     1018
"UTF-32"     1017
"UTF-16LE"     1014
"UTF-16BE"     1013
"UTF-16"     1015
"System"     0
"Big5-HKSCS"     2101
"Big5"     2026
"windows-949"     -949
"EUC-KR"     38
"Shift_JIS"     17
"ISO-2022-JP"     39
"EUC-JP"     18
"GB2312"     2025
"GBK"     113
"GB18030"     114
"hp-roman8"     2004
"TIS-620"     2259
"WINSAMI2"     -165
"macintosh"     2027
"windows-1258"     2258
"windows-1257"     2257
"windows-1256"     2256
"windows-1255"     2255
"windows-1254"     2254
"windows-1253"     2253
"windows-1252"     2252
"windows-1251"     2251
"windows-1250"     2250
"IBM866"     2086
"IBM874"     -874
"IBM850"     2009
"ISO-8859-16"     112
"ISO-8859-14"     110
"ISO-8859-13"     109
"ISO-8859-10"     13
"ISO-8859-9"     12
"ISO-8859-8"     85
"ISO-8859-7"     10
"ISO-8859-6"     82
"ISO-8859-5"     8
"ISO-8859-4"     7
"ISO-8859-3"     6
"ISO-8859-2"     5
"KOI8-U"     2088
"KOI8-R"     2084
"iscii-mlm"     -3008
"iscii-knd"     -3007
"iscii-tlg"     -3006
"iscii-tml"     -3005
"iscii-ori"     -3004
"iscii-gjr"     -3003
"iscii-pnj"     -3002
"iscii-bng"     -3001
"iscii-dev"     -3000
"TSCII"     2107


//                const char *name1="GB2312";
////                QTextCodec *codecdes = QTextCodec::codecForName(QObject::tr("GB2312"));
////                QTextCodec *codecdes = QTextCodec::codecForMib(2025);//! GB2312
//                QTextCodec *codecdes = QTextCodec::codecForMib(106);//! "UTF-8"     106
//                QByteArray encodedData=serviceClass.toLatin1();
//                QTextStream in(&encodedData);
//                in.setAutoDetectUnicode(false);
//                in.setCodec(codecdes);
//                QString decodedStr = in.readAll();
//                int i=90;


下面是用QT的语言专家来解决的QT中的中文问题,方法如下:
先在工程PRO中
TRANSLATIONS+=abcd.ts
然后QMAKE, xxxx.png
更新编译,然后再打开QT语言专家,在语言专家中可以看到你的类,类下面的所有以tr()开关的字符串---注意:所有要翻译的字符串,代码中必须用 英文 来写,然后翻译的时候,翻译成中文,然后翻译好后,点击保存,发布,再在代码的MAIN.cpp中添加如下代码:
#include
QTranslator *tr = new QTranslator;
    tr->load("../demos/xxx/ttt/xxx.qm");
    app.installTranslator(tr);
   可以把这个生成的ts文件添加到工程中,每次翻译后,都要保存,发布QT下面的中文乱码问题_第3张图片QT下面的中文乱码问题_第4张图片

也可以对界面上的进行翻译 ,同样的原理 界面上有一个属性,可翻译的,就表示这个意思 (tr)


下面是另外一

LangSwitch.h:
#ifndef LangSwitch_H
#define LangSwitch_H

#include 
#include 
#include 

class LangSwitch : public QWidget
{
    Q_OBJECT

public:
    LangSwitch(QWidget *parent = 0);
    ~LangSwitch();
private slots:
    void changeLang(int indexx);
private:
    void createScreen();
    void changeTr(const QString & langCode);
    void refreshLabel();

    QComboBox* combo;
    QLabel *label;
};
#endif // MAINWINDOW_H
LangSwitch.cpp:
#include "LangSwitch.h"
#include 
#include 
#include 
#include 

LangSwitch::LangSwitch(QWidget *parent) :
    QWidget(parent)
{
    createScreen();
}

LangSwitch::~LangSwitch()
{
}

void LangSwitch::changeLang(int indexx)
{
    QString langCode=combo->itemData(indexx).toString();
    changeTr(langCode);
    refreshLabel();
}

void LangSwitch::createScreen()
{
    combo=new QComboBox;
    combo->addItem("English","en");
    combo->addItem("Chinese","zh");
    combo->addItem("Latin","la");

    label=new QLabel;
    refreshLabel();

    QVBoxLayout *layout=new QVBoxLayout;
    layout->addWidget(combo,1);
    layout->addWidget(label,5);

    setLayout(layout);

    connect(combo,SIGNAL(currentIndexChanged(int)),this,SLOT(changeLang(int)));
}

void LangSwitch::changeTr(const QString &langCode)
{
    static QTranslator *translatort;
    if(translatort!=NULL)
    {
        qApp->removeTranslator(translatort);
        delete translatort;
        translatort=NULL;
    }
    translatort=new QTranslator;
    QString qmFilename="lang_"+langCode;
    QString ss=QDir::currentPath();//E:\delcode\build-untitled-Desktop_Qt_5_5_1_MSVC2010_32bit_qt_55_w-Debug
    //if(translatort->load(QString("../")+qmFilename))
    if(translatort->load(qmFilename))//详见load的说明,首先加载 的是ss中的 .qm 文件 所以要更新,还要发布 其实所有的qm文件是同一份,会对应不同的数据 取值
    {
        qApp->installTranslator(translatort);
    }
}

void LangSwitch::refreshLabel()
{
    label->setText(tr("TXT_HELLO_WORLD","Hello World"));// Hello World 出现在开发人员注释那里,这样可以给开发人员提醒。
}

有些代码中是不基于QObject 的,下面是代码中的解决方案,以及图:

class xx
{
public:
    Q_DECLARE_TR_FUNCTIONS(xx)
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //! TRANSLATIONS+=$$PWD/debug/win.ts
    QTranslator trX;
    QString strdir = QCoreApplication::applicationDirPath();
    QString qmStr = strdir+"/win.qm";
    trX.load(qmStr);
    a.installTranslator(&trX);

    QTextStream errorStream(stderr);
    if (argc != 2)
    {
        QString s = xx::tr( "Usage: xmlstreamlint ");
        errorStream << s;
        return 2;
    }

    return a.exec();
}
图:

QT下面的中文乱码问题_第5张图片


 
  
先看图:

QT下面的中文乱码问题_第6张图片QT下面的中文乱码问题_第7张图片QT下面的中文乱码问题_第8张图片QT下面的中文乱码问题_第9张图片


你可能感兴趣的:(QT学习)