Вывод UTF-8 с помощью qInstallMsgHandler - PullRequest
1 голос
/ 24 июля 2011

Я хотел бы, чтобы мой обработчик отладки (установленный с 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 ]

3 голосов
/ 28 июля 2011

Если вы пройдете по коду в отладчике, вы обнаружите, что QDebug и qt_message сначала создают QString из const char *, а затем используют toLocal8Bit для этой строки.

Единственный способ обойти это: использовать свое собственное кодирование (что-то вроде «[E68891]») или другое кодирование, такое как кодирование uu или base64, которое использует только символы ASCII и декодирует строку в вашем обработчик сообщений.

Вам также следует рассмотреть возможность использования версии qDebug ("% s", "string"), чтобы избежать кавычек и дополнительных пробелов (см. Этот вопрос ).

Редактировать : toLocal8Bit происходит в деструкторе QDebug, который вызывается в конце оператора qDebug (qdebug.h, строка 85). По крайней мере, на платформе Windows это вызывает toLatin1, что неправильно интерпретирует строку. Вы можете предотвратить это, вызвав следующие строки в начале вашей программы:

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

На некоторых платформах UTF-8 является текстовым кодеком по умолчанию.

1 голос
/ 28 июля 2011

Проблема в том, что метод operator<<(const char *) ожидает строку в кодировке Latin1, поэтому вы должны передать правильный UTF-8 QString в QDebug, например:

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

...и изнутри обработчик сообщений ожидает строку UTF-8:

QString message = QString::fromUtf8(msg);

И это должно работать как шарм.;)

Для получения дополнительной информации, пожалуйста, прочитайте справочное руководство QDebug .

Вы также можете поступить неправильно: продолжайте передавать кодированные строки 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 из обработчика сообщений, но я STRONGLY рекомендую вам создать его экземпляр.

Одна вещь, которую вы должны быть уверены, это то, чтоВаш файл исходного кода кодируется в UTF-8.Для этого вы можете использовать соответствующий инструмент для проверки (например, file в случае использования Linux) или просто позвонить QMessageBox::information(NULL, NULL, QString::fromUtf8("我"), QMessageBox::Ok) и посмотреть, появляется ли правильное сообщение.

1 голос
/ 25 июля 2011

попытайтесь передать данные в UTF8 и извлечь их в вашей функции с помощью чего-то вроде

QString::fromUTF8

, для этого требуется const char * на входе.

0 голосов
/ 28 июля 2011
#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, потому что в противном случае в этом месте будет показан другой символ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...