QTextCodec::codecForName
Qt 中 QTextCodec::codecForName("GB18030") 返回为 NULL 的解决
现象:
类似一下代码
QTextCodec* localCode = QTextCodec::codecForName("GB18030");
QTextCodec::setCodecForCStrings(localCode);
此处,localCode返回的为Null
原因:
Qt中的字体编码分为内置编码以及plugin编码,内置的编码类型可以通过运行%QTDIR%/examples\tools\codecs查看。
可以codecs中看到,默认的文字编码类型不包含GBK、GB18030、GB2312。
通过查阅%QTDIR%/src/plugins文件夹可以发现,其下存在一个名为codecs的文件夹,而其中正包含了cn、jp、kr、tw四类编码格式并且在%QTDIR%/plugins/codecs下也找到了对应的lib以及dll(区分链接方式)。
解决方案:
手动加入对codecsplugins的支持。
实现步骤:
1,拷贝对应lib以及dll到qt的bin以及lib中(区分qt链接的方式);
2,在include中新建plugins目录,里面新建一文件Textcodec有如下行:
#include "../../../src/plugins/codecs/cn/qgb18030codec.h"
3,从QTextCodecPlugins继承一个类,内容如下
.h:
1: #ifndef __WEX_TEXTCODECPLUGIN_H_INCLUDED
2: #define __WEX_TEXTCODECPLUGIN_H_INCLUDED
3:
4: #include
5: #include
6:
7: class WTextCodecPlugin : public QTextCodecPlugin
8: {
9: Q_OBJECT
10:
11: public:
12: WTextCodecPlugin(QObject* parent = 0);
13: virtual ~WTextCodecPlugin();
14:
15: public:
16:
17: virtual QList names () const;
18:
19: virtual QTextCodec * createForName ( const QByteArray & name );
20:
21: virtual QList mibEnums () const;
22:
23: virtual QTextCodec * createForMib ( int mib );
24:
25: virtual QList aliases () const;
26: };
27:
28: static WTextCodecPlugin __g_w_textcodeplugin;
29:
30: static QTextCodec* WGetTextCodeForName(const QByteArray & name)
31: {
32: return __g_w_textcodeplugin.createForName(name);
33: }
34:
35: typedef WTextCodecPlugin WexTextCodecPlugin;
36:
37: #endif
.cpp:
1: #include "WexTextCodecPlugin.h"
2: #include
3: #include
4:
5: WTextCodecPlugin::WTextCodecPlugin(QObject* parent)
6: : QTextCodecPlugin(parent)
7: {
8:
9: }
10:
11: WTextCodecPlugin::~WTextCodecPlugin()
12: {
13:
14: }
15:
16: QList WTextCodecPlugin::names() const
17: {
18: return QList() << QGbkCodec::_name() << QGb18030Codec::_name() << QGb2312Codec::_name();
19: }
20:
21: QTextCodec* WTextCodecPlugin::createForName( const QByteArray & name )
22: {
23: if (name == QGbkCodec::_name())
24: return new QGbkCodec();
25: else if (name == QGb18030Codec::_name())
26: return new QGb18030Codec();
27: else if (name == QGb2312Codec::_name())
28: return new QGb2312Codec();
29:
30: return 0;
31: }
32:
33: QList WTextCodecPlugin::aliases() const
34: {
35: return QList() << QGbkCodec::_aliases() << QGb18030Codec::_aliases() << QGb2312Codec::_aliases();
36: }
37:
38: QList WTextCodecPlugin::mibEnums() const
39: {
40: return QList() << QGbkCodec::_mibEnum() << QGb18030Codec::_mibEnum() << QGb2312Codec::_mibEnum();
41: }
42:
43: QTextCodec* WTextCodecPlugin::createForMib( int mib )
44: {
45: if (mib == QGbkCodec::_mibEnum() )
46: return new QGbkCodec();
47: else if ( mib == QGb18030Codec::_mibEnum() )
48: return new QGb18030Codec();
49: else if ( mib == QGb2312Codec::_mibEnum() )
50: return new QGb2312Codec();
51:
52: return 0;
53: }
4,最后即可在原先的地方如下书写
1: #include "WexTextCodecPlugin.h"
2:
3: QApplication a(argc, argv);
4: QTextCodec* localCode = WGetTextCodeForName("GB18030");
5: QTextCodec::setCodecForCStrings(localCode);
5,项目中附加的lib库中添加
qcncodecsd.lib 或者 qcncodecs.lib (debug、release)
跟踪可以看出loaclCode已经!=0
运行,乱码问题消失
注:
经测试,如果项目中有用到QtXml库,并且XML文件中定义的编码不是UTF-8等内置格式,如GBK。
那么,有可能出现如下症状,
编译好的程序,debug和release均可在本机运行,然而换一台机器,则发现xml不能正确处理
跟踪QXmlStreamReader可以发现:xml中的所有项目都读取失败了。
通过本篇的方法,也可以解决该问题。