声明:本人学习QT不到七天,QT的好多东西还不是很清楚,说的不对的,大家不要见笑。
QT版本:4.6.1
VC版本:VC6
MYSQL版本:5.0.22
本文要解决的问题:
已安装MYSQL5.0.22,数据库使用UTF-8编码。数据库中所有设计字符串的字段都是用binary类型(字段类型为什么不用varchar,数据库为什么不用GBK编码,呵呵,历史原因)。VC中向数据库的字符串字段写入中文,要求能在QT中读出并写到XML文件中,XML也采用UTF-8编码。
思路:
大家都知道在VC中默认的字符串都是ANSI格式的,如果不做任何转换就写到数据库的binary字段中,通过VC读出肯定不会有问题。但在QT中直接读出来就是乱码,网上说是因为QT默认的是UTF-8编码,我不知道是对不对。假设网上说的是对的,现在的问题就很明白了,其实就是ANSI与UTF-8之间的编码转换问题。
解决方法:
1 要么在VC中写数据库之前,将字符串转为UTF-8编码。
2 要么在QT读到字符串时,将其转为UTF-8编码。
因为项目原因,只能采取方法2:
因为对QT不熟悉,关于字符串编码的转换函数找的很费劲,最好摸索出一个方法,定义一个转换宏来处理:
#define ANSITOUTF8(a) QString::fromLocal8Bit(a.data()).toUtf8()
举例如下:
bool LoadStation(QSqlDatabase& db)
{
QSqlQueryModel query;
int i = 0;
query.setQuery("select * from Station_Cfg_T", db);
for(i = 0; i < query.rowCount(); i++)
{
g_stuSta.sid = query.record(i).value("Station_ID").toInt();
g_stuSta.name = ANSITOUTF8(query.record(i).value("Station_Name").toByteArray());
g_stuSta.disknum = query.record(i).value("Disk_Num").toInt();
g_stuSta.disksize = query.record(i).value("Disk_Size").toInt();
g_stuSta.smvsize = query.record(i).value("Smv_Size").toInt();
g_stuSta.othersize = query.record(i).value("Other_Size").toInt();
g_stuSta.tmsource = query.record(i).value("Time_Source").toInt();
g_stuSta.storemode = query.record(i).value("Store_Mode").toInt();
break;//不用奇怪,此表只有一行
}
printf("获取Station_Cfg_T %d 行内容!\n", i);
return (i > 0);
}
但就这样仍然不行,在MAIN函数中加入如下三行(来自网上):
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
看意思是设置编码格式为UTF-8,但如网上大侠所说,QT默认的是UTF-8编码,何必要进行设置呢,疑问?????
完整main示例如下:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
printf("打印已安装的SQL驱动!\n");
qDebug() << QSqlDatabase::drivers();
printf("从数据库读取配置信息!\n");
LoadCfgInfo();
SaveCfgToXml("c:\\temp.xml");
return a.exec();
}
顺便附上一个写XML的例子,从书上照搬的,呵呵。
bool SaveCfgToXml(QString path)
{
if(path.isNull() || path.isEmpty())
return false;
QFile file(path);
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
return false;
}
QDomDocument doc;
QDomElement elem, root;
QDomAttr attr;
QDomProcessingInstruction instruction;
instruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(instruction);
root = doc.createElement("wea800");
doc.appendChild(root);
elem = doc.createElement("station_cfg_t");
attr = doc.createAttribute("Station_ID");
attr.setValue("1");//还不知道怎么将数字写到属性值中,呵呵,刚看到了,用QString::number(g_stuSta.sid)
elem.setAttributeNode(attr);
attr = doc.createAttribute("Station_Name");
attr.setValue(g_stuSta.name.toUtf8());
elem.setAttributeNode(attr);
root.appendChild(elem);
QTextStream out(&file);
doc.save(out, 4);
return false;
}
[ 此帖被dd970512在2010-02-27 11:52重新编辑 ]