qInstallMessageHandler 问题
fprintf是ANSI的,UNICODE的,要用fwprintf;也可以用_ftprintf来同时兼容ANSI和UNICODE;
The default message handler prints the message to the standard output under X11 or to the debugger under Windows. If it is a fatal message, the application aborts immediately.
Only one message handler can be defined, since this is usually done on an application-wide basis to control debug output.
To restore the message handler, call qInstallMessageHandler(0).
Example:
#include <qapplication.h>
#include <stdio.h>
#include <stdlib.h>
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtInfoMsg:
fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
abort();
}
}
int main(int argc, char **argv)
{
qInstallMessageHandler(myMessageOutput);
QApplication app(argc, argv);
...
return app.exec();
}
This function was introduced in Qt 5.0.
qt Release 版本日志:文件名、函数名、行数—解决办法
qInstallMessageHandler来实现输出详细日志,输出文件名,行号,所在函数及事件,并写入文件。最后调用系统原来的函数,使信息像之前一样输出到调试窗口,便于开发。
QtMessageHandler gDefaultHandler = NULL;
//在其它地方调用qInstallMessageHandler设置新的输出函数,但保存原来的函数
gDefaultHandler = qInstallMessageHandler(myMessageOutput);
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QDateTime time = QDateTime::currentDateTime();
QString strTime = time.toString("MM-dd hh:mm:ss");
QString strMessage = QString("%1 File:%2 Line:%3 Function:%4\r\n %5")
.arg(strTime).arg(context.file).arg(context.line).arg(context.function).arg(msg);
QString strMsg("");
switch(type)
{
case QtDebugMsg:
strMsg = QString("Debug");
break;
case QtInfoMsg:
strMsg = QString("Info");
break;
case QtWarningMsg:
strMsg = QString("Warning:");
break;
case QtCriticalMsg:
strMsg = QString("Critical:");
break;
case QtFatalMsg:
strMsg = QString("Fatal:");
break;
default:
strMsg = QString("Err");
break;
}
strMessage = strMsg+strMessage;
// 加锁
static QMutex mutex;
mutex.lock();
// 输出信息至文件中(读写、追加形式)
QFile file("D:\\log.txt");
file.open(QIODevice::ReadWrite | QIODevice::Append);
QTextStream stream(&file);
stream << strMessage << "\r\n";
file.flush();
file.close();
// 解锁
mutex.unlock();
//用系统原来的函数完成原来的功能. 比如输出到调试窗
if(gDefaultHandler)
{
gDefaultHandler(type,context,msg);
}
}
上面代码里使用gDefaultHandler 保留了qInstallMessageHandler返回的系统原来的函数,最后再调用。这样qDebug()、qInfo()的信息和之前一样写入调试窗口,同时也写入了文件。
Release 版本默认不包含这些信息:文件名、函数名、行数,需要在项目文件加入以下代码,加入后最好重新构建项目使之生效:
DEFINES += QT_MESSAGELOGCONTEXT
Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK 乱码与转码问题
代码如下:如果不不设全局的字符集是utf-8,那么网上一般的方法是可以转的。如下程序中 #define DD 1的情况下;但是如果设置了全局的utf-8,再用以前的方法:
QByteArray ba=aaa.toLatin1();
const char *c_str = ba.data();
PS:c_str所指向的内存单元,如果你想长时间使用你应该复制出来,要不可能过数行代码后,你再读你的数据,c_str所指向的内存单元就不是你以前读的内容了。函数返回的指针临时变量,不能长时间使用!!!!!!!
具体代理在本贴最后补充出来:
等网上类似的方法,都会出现转代汉字不成功,但能转代ASICC码的情况。汉字都成了问号的ASICC码63。这是因为没有用对方法没有用转换utf-8码的方法。
转码是件很复杂的事。
#include <QtGui/QApplication>
#include<QTextCodec>
#include<QFont>
#include<QtGui>
#include <QByteArray>
#define DD 0
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
#if DD
//没有设置全局的是utf-8字符
#else
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
QFont font;
font.setFamily(("WenQuanYi Zen Hei"));
font.setPointSize(12);
app.setFont(font);
app.setFont(font);
#endif
QString aaa= "你好a1234";
QString bbb="哈哈afaf394的AAA";
#if DD
QByteArray ba=aaa.toLatin1();
const char *c_str = ba.data();
printf("c_str:%s:size=%d\n",c_str,strlen(c_str));
char *p;
p=(char *)c_str;
printf("p=%d\n",*p);
p++;
printf("p=%d\n",*p);
QString ddd(c_str);
qDebug()<<ddd;
#else
char *ad = aaa.toUtf8().data();
char *bb= bbb.toUtf8().data();
printf("ad=%s,size=%d\n",ad,strlen(ad));
printf("df=%s,size=%d\n",bb,strlen(bb));
#endif
QPushButton ccc("AWQ WQ wq 你了");
ccc.show();
return app.exec();
}
以下是在网上找的,感觉很好,可以一块理解:
这个好像就是用几种不同的字符,但不会出错,不像我们一种都搞不定
Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK
#include <QFile>
#include <QFileDialog>
#include <QTextCodec>
#include <QByteArray>
void MainWindow::on_pushButton_clicked()
{
/*
只有8位编码的才需要tr, unicode不要tr
gb2312是GBK的子集,通常设成哪个都一样的
所谓的QString转char*,结果并不相同,根据编码格式不同而不同
QString转unicode,不用转,QString本身就是unicode
QString的根本是QChar数组,但不是以0结尾,有大小,QChar的根本是ushot
Qt中unicode声明:可以用wchar_t,也可以用ushot,没有WCHAR
QByteArray可以理解为char类型的动态数组,有大小,不是以\0结尾
*/
/*
ui创建1个列表框QListWidget,和1个按钮即可
用windows记事本分别创建4种文件,本例可直接打开
ANSI:没有文件头,2字节/汉字,1字节/英文
UTF-8:文件头[0xEF,0xBB,0xBF],3字节/汉字,1字节/英文
Unicode:文件头[0xFF,0xFE],2字节/汉字,2字节/英文
Unicode big endian :文件头[0xFE,0xFF],同Unicode,字节序相反
QString转char*的规则同上;
*/
/*
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
QTextCodec::setCodecForTr(QTextCodec::codecForName("gb2312"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
如下使用想要得到正确结果必须使用类似以上的语句
str = tr("显示中文");
但以下这个可以直接使用
strText = QString::fromLocal8Bit("显示中文");
*/
ui->list->addItem(QString::fromLocal8Bit("--------显示中文----------"));
QString strFileName = QFileDialog::getOpenFileName(this, tr("OpenFile"), ".", tr("Image Files(*.*)"));
if(strFileName.length() == 0)
{
ui->list->addItem(tr("You didn't select any files."));
return;
}
// 打开文件
QFile *pFile = new QFile(strFileName);
if (!pFile->open(QFile::ReadOnly))
{
ui->list->addItem(tr("open file fail %1: %2.").arg(strFileName).arg(pFile->errorString()));
return;
}
ui->list->addItem(tr("open file ok %1").arg(strFileName));
// 读文件
qint64 fileSize = pFile->size();
ui->list->addItem(tr("size = %1").arg(fileSize));
char *pBuf = new char[fileSize];
pFile->read(pBuf, fileSize);
pFile->close();
if(fileSize < 4)
{
ui->list->addItem(tr("fileSize < 4"));
return;
}
QString strText;
uchar *p = (uchar*)pBuf;
if(p[0] == 0xEF && p[1] == 0xBB && p[2] == 0xBF)// UTF-8
{
ui->list->addItem(tr("UTF-8"));
strText = QString::fromUtf8(pBuf + 3, fileSize - 3);
}
else if(p[0] == 0xFF && p[1] == 0xFE)// Unicode
{
ui->list->addItem(tr("Unicode"));
strText = QString::fromWCharArray((wchar_t*)(pBuf + 2), (fileSize - 2) / 2);
}
else if(p[0] == 0xFE && p[1] == 0xFF)// Unicode big endian
{
ui->list->addItem(tr("Unicode big endian"));
uchar uc = 0;
for(int i = 3; i < fileSize; i += 2)
{
uc = p[i];
p[i] = p[i - 1];
p[i - 1] = uc;
}
strText = QString::fromWCharArray((wchar_t*)(pBuf + 2), (fileSize - 2) / 2);
}
else //ANSI
{
ui->list->addItem(tr("ANSI"));
strText = QString::fromLocal8Bit(pBuf, fileSize);
}
ui->list->addItem(strText);
QString strMsg, strTmp;
//转unicode
strMsg = tr("unicode: ");
QChar *pData = strText.data();
for(int i = 0; i < strText.size(); i++)
{
strTmp = tr("0x%1, ").arg(QString::number(pData[i].unicode(), 16).toUpper());
strMsg += strTmp;
}
ui->list->addItem(strMsg);
// 转gb2312
strMsg = tr("gb2312: ");
QByteArray ary1 = strText.toLocal8Bit();
uchar *puchar = (uchar*)ary1.data();
for(int i = 0; i < ary1.size(); i++)
{
strTmp = tr("0x%1, ").arg(QString::number(puchar[i], 16).toUpper());
strMsg += strTmp;
}
ui->list->addItem(strMsg);
// 转uft8
strMsg = tr("utf-8: ");
ary1 = strText.toUtf8();
puchar = (uchar*)ary1.data();
for(int i = 0; i < ary1.size(); i++)
{
strTmp = tr("0x%1, ").arg(QString::number(puchar[i], 16).toUpper());
strMsg += strTmp;
}
ui->list->addItem(strMsg);
ui->list->addItem(tr(" "));
}
以下这个我认为是中文字符的深入理解吧:
QString 与中文问题
(更新:本文的姊妹篇 Qt中translate、tr关系 与中文问题 )
首先呢,声明一下,QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给QString。
很简单的问题, “我是中文” 这样写的时候,它是传统的 char 类型的窄字符串,我们需要的只不过是通过某种方式告诉QString 这四个汉字采用的那种编码。而问题一般都出在很多用户对自己当前的编码没太多概念,
QString 与中文问题
https://www.cnblogs.com/bingcaihuang/archive/2011/03/17/1986895.html