使用qInstallMsgHandler输出UTF-8

时间:2011-07-24 05:01:14

标签: debugging qt utf-8

我想让我的调试处理程序(与qInstallMsgHandler一起安装)处理UTF-8,但似乎它只能被定义为void myMessageOutput(QtMsgType type, const char *msg)const char*不能解决问题处理UTF-8(一旦显示,它只是随机字符)。

有没有办法将此功能定义为void myMessageOutput(QtMsgType type, QString msg),或者可能采用其他方式使其有效?

这是我目前的代码:

void myMessageOutput(QtMsgType type, const char *msg) {
    QString message = "";

    QString test = QString::fromUtf8(msg);

    // If I break into the debugger here. both "test" and "msg" contain a question mark.

    switch (type) {

        case QtDebugMsg:
        message = QString("[Debug] %1").arg(msg);
        break;

        case QtWarningMsg:
        message = QString("[Warning] %1").arg(msg);
        break;

        case QtCriticalMsg:
        message = QString("[Critical] %1").arg(msg);
        break;

        case QtFatalMsg:
        message = QString("[Fatal] %1").arg(msg);
        abort();

    }

    Application::instance()->debugDialog()->displayMessage(message);
}



Application::Application(int argc, char *argv[]) : QApplication(argc, argv) {
    debugDialog_ = new DebugDialog();
    debugDialog_->show();

    qInstallMsgHandler(myMessageOutput);

    qDebug() << QString::fromUtf8("我");
}

4 个答案:

答案 0 :(得分:3)

如果您单步执行调试器中的代码,您会发现QDebug和qt_message首先从const char *构造一个QString,然后在此字符串上使用toLocal8Bit。

我能想到绕过这个的唯一方法:使用你自己的编码(类似“[E68891]”)或其他编码,如uu-encode或base64-encoding,只使用ASCII字符并解码你的字符串消息处理程序。

您还应该考虑使用版本qDebug(“%s”,“string”)来避免引号和其他空格(请参阅此question)。

编辑:toLocal8Bit发生在QDebug的析构函数中,该析构函数在qDebug语句的末尾调用(qdebug.h第85行)。至少在Windows平台上,这会调用Latin1,从而误解字符串。您可以通过在程序开头调用以下行来阻止这种情况:

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

在某些平台上,UTF-8似乎是默认的文本编解码器。

答案 1 :(得分:1)

尝试在UTF8中传递数据并使用类似

之类的函数将其提取出来
QString::fromUTF8

输入时需要使用const char *。

答案 2 :(得分:1)

问题是operator<<(const char *)方法需要一个Latin1编码的字符串,因此您应该将正确的UTF-8 QString传递给QDebug,如下所示:

qDebug() << QString::fromUtf8("我");

...并且从消息处理程序内部得到一个UTF-8字符串:

QString message = QString::fromUtf8(msg);

这应该像魅力一样。 ;)

有关详细信息,请阅读QDebug reference manual

你也可能做错了:继续通过<<传递UTF-8编码的字符串,并使用可怕的QString::fromUtf8(QString::fromUtf8(msg).toAscii().constData())调用转换字符串。

编辑:这是有效的最终示例:

#include <QString>
#include <QDebug>
#include <QMessageBox>
#include <QApplication>

void
myMessageOutput(QtMsgType type, const char *msg)
{
    QMessageBox::information(NULL, NULL, QString::fromUtf8(msg), QMessageBox::Ok);
}

int
main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qInstallMsgHandler(myMessageOutput);
    qDebug() << QString::fromUtf8("我");

    return 0;
}

请注意,如果您未实例化QDebug,则QApplication不会进行任何字符集转换。这样您就不需要在消息处理程序中对msg执行任何特殊操作,但我强烈建议您实例化它。

您必须确定的一件事是您的源代码文件是以UTF-8编码的。为此,您可以使用适当的工具进行检查(例如,如果您使用Linux,则为file),或者只需拨打QMessageBox::information(NULL, NULL, QString::fromUtf8("我"), QMessageBox::Ok)并查看是否显示正确的消息。

答案 3 :(得分:0)

#include <QtCore/QCoreApplication>
#include <stdio.h>
#include <QDebug>

void myMessageOutput(QtMsgType type, const char *msg)
{
  fprintf(stderr, "Msg: %s\n", msg);
}

int main(int argc, char *argv[])
{
  qInstallMsgHandler(myMessageOutput);

  QCoreApplication a(argc, argv);

  qDebug() << QString::fromUtf8("我");    
}

上面的代码完全适用于此,但我必须强调我的控制台确实支持UTF-8,因为如果它不会在那个位置显示另一个字符。