Qt/C++ - Lesson 050. Logging Qt application events to a text file

All developers uses macro qDebug() , when debugging an application written in the Qt, but there are also macros qInfo(), qWarning(), qCritical() and qFatal() (which, as of this writing has errors and did not work).

With these events, you can divide errors in the application on the level of significance and use filters.

To redirect error messages to a text file, you need to install the CallBack-function handler into the application. For this purpose qInstalMessageHandler function.

The signature handler must be as follows:

void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);

Through it, we will receive the following information:

  1. QtMsgType type - Message Type
    1. QtInfoMsg
    2. QtDebugMsg
    3. QtWarningMsg
    4. QtCriticalMsg
    5. QtFatalMsg
  2. QMessageLogContext &context - context of a message, the most useful of it - this is the message category. What is important when working with data output can be used, and additional categories, due to which it is possible to improve the localization of posts in the component of the program, if you used the same number of messages.
  3. QString &msg - message transmitted in error logging

Additional categories - QLoggingCategory

Additional categories are objects QLoggingCategory class. There may be several approaches to work with the categories, for example, you can create a category object in any class and pass it to an error conclusion:

QLoggingCategory  m_category("Test");
qDebug(m_category) << "Check it";

Then we obtain the following output:

Test: Check it

Inconvenience approach is that each will generate a class data category and some grades they generally can be the same. Therefore, we use a different approach. Namely registration category by the macro.


We declare four different categories.

#ifndef LOGGER_H
#define LOGGER_H

#include <QLoggingCategory>


#endif // LOGGER_H


Assign data names of categories.

#include "LoggingCategories.h"

Q_LOGGING_CATEGORY(logDebug,    "Debug")
Q_LOGGING_CATEGORY(logInfo,     "Info")
Q_LOGGING_CATEGORY(logWarning,  "Warning")
Q_LOGGING_CATEGORY(logCritical, "Critical")

Using LoggingCategories

In order to take advantage of these categories, you must include the header file in the file where we will use these categories. And use them as follows:

qDebug(logDebug()) << "Check it";

Then we obtain the following output:

Debug: Check it

Installing the handler

To demonstrate the handler we will use graphics application, which will has four buttons:

  • Debug
  • Info
  • Warning
  • Critical

In the handler of each button will cause a corresponding macros logging of events and to apply the appropriate categories listed above. Window application created by a graphic designer and is as follows.



#include <QMainWindow>

namespace Ui {
class MainWindow;

class MainWindow : public QMainWindow

    explicit MainWindow(QWidget *parent = 0);

private slots:
    void on_debugButton_clicked();
    void on_infoButton_clicked();
    void on_warningButton_clicked();
    void on_criticalButton_clicked();

    Ui::MainWindow *ui;

#endif // MAINWINDOW_H


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

#include "LoggingCategories.h"

MainWindow::MainWindow(QWidget *parent) :
    ui(new Ui::MainWindow)

    delete ui;

void MainWindow::on_debugButton_clicked()
    qDebug(logDebug()) << "Debug Button";

void MainWindow::on_infoButton_clicked()
    qInfo(logInfo()) << "Info Button";

void MainWindow::on_warningButton_clicked()
    qWarning(logWarning()) << "Warning Button";

void MainWindow::on_criticalButton_clicked()
    qCritical(logCritical()) << "Critical Button";


#include "mainwindow.h"
#include <QApplication>
#include <QFile>
#include <QDir>
#include <QScopedPointer>
#include <QTextStream>
#include <QDateTime>
#include <QLoggingCategory>

// Smart pointer to log file
QScopedPointer<QFile>   m_logFile;

void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);

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

    // Set the logging file
    // check which a path to file you use 
    m_logFile.reset(new QFile("C:/example/logFile.txt"));
    // Open the file logging
    m_logFile.data()->open(QFile::Append | QFile::Text);
    // Set handler

    MainWindow w;

    return a.exec();

// The implementation of the handler
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
    // Open stream file writes
    QTextStream out(m_logFile.data());
    // Write the date of recording
    out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz ");
    // By type determine to what level belongs message
    switch (type)
    case QtInfoMsg:     out << "INF "; break;
    case QtDebugMsg:    out << "DBG "; break;
    case QtWarningMsg:  out << "WRN "; break;
    case QtCriticalMsg: out << "CRT "; break;
    case QtFatalMsg:    out << "FTL "; break;
    // Write to the output category of the message and the message itself
    out << context.category << ": "
        << msg << endl;
    out.flush();    // Clear the buffered data


As a result, the file of logging events will created in the folliwnf path C:\example\logFile.txt.

By pressing the buttons in the application window, the contents of the file will look like this:

2016-06-04 17:05:57.439 DBG Debug: Debug Button
2016-06-04 17:05:57.903 INF Info: Info Button
2016-06-04 17:05:58.367 WRN Warning: Warning Button
2016-06-04 17:05:58.815 CRT Critical: Critical Button

Download Qt application with logging into text file

Video lesson

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate

Добрый день. А как сделать, что бы ещё и в консоль выводилось?

Добрый день

Многого хотите ))) Установка обработчика же как раз для того, чтобы перенаправить вывод qDebug в файл.
Вывод здесь забирается и перенаправляется в файл. Но если так сильно хочется выводить в консоль, то используйте std::cout в обработчике сообщений.

  • #
  • Aug. 15, 2017, 6:08 a.m.

Важно упомянуть, что QLoggingCategory в QT начиная с 5 версии.

А кто-то ещё использует Qt4? )))


Мало ли ) Мне для взаимодействия с библиотеками Octave приходится)

Это который GNU Octave? Сочувствую тогда... в Qt5 много полезный вкусностей.


Он самый

Я полистал информацию в интернетах, вроде как кто-то пытается подружить его с Qt5, но успешных результатов не нашёл. Да и на сайте как-то не заметно информации о том, что конкретно ему нужно, какая именно версия Qt требуется.

Как здесь кириллицу корректно использовать?

Q_LOGGING_CATEGORY(logWarning,  "Предупреждение")

Фух фух фух.... не люблю я для таких вещей кириллицу использовать ;-)

Но может Вам поможет вот этот топик .
Здесь скорее всего нужно правильно с кодировкой поколдовать.

А что мешает сохранить адрес дефолтного обработчика и после вывода в файл вызывать и его?

Хм.. Как-то даже не подумал ))


таки да, используется, причем активно


таки да. используется

Мне видимо нужно было добавить тег /sarcasm ?
Всем ясно, что legaci есть и будет, но это не значит, что я, например, добровольно полезу болото месить.


Only authorized users can post comments.
Please, Log in or Sign up
How to become an author?

Contribute to the evolution of the EVILEG community.

Learn how to become a site author.

Learn it

Good day, Dear Users!!!

I am Evgenii Legotckoi, developer of EVILEG. And it is my hobby project, which helps to learn programming another programmers and developers

If the site helped you, and you want also support the development of the site, than you can donate by following ways


Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting Timeweb
May 26, 2020, 11:29 a.m.
Artem Sun-Dun-Chan

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
May 25, 2020, 11:33 a.m.
Mitja Nagibin

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
May 25, 2020, 5:05 a.m.

C++ - Test 001. The first program and data types

  • Result:66points,
  • Rating points-1
Last comments
May 28, 2020, 3:14 p.m.
Evgenij Legotskoj

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Ну в моём примере, который в статье сработало так model->setData(model->index(1, 1), 7); Поскольку model->index(1, 0) - это индекс колонки id, которая скрыта, поэтому…
May 28, 2020, 3:08 p.m.
Mihail A

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Спасибо, завтра првоерю. А model->setData(model->index(1, 0), 7); Тоже заработало?
May 28, 2020, 3:06 p.m.
Evgenij Legotskoj

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Да, метод data всё-таки влиял, я переписал его так и заработало удаление QVariant TableModel::data(const QModelIndex &idx, int role) const{ if (role == Qt::BackgroundColorRole) {…
May 28, 2020, 2:49 p.m.
Evgenij Legotskoj

Django - Tutorial 011. Adding comments to the site based on Django

Он более функциональный и его функционал объективно лучше поддерживается Django. Из первого, что приходит на ум: Это наличие полей типа Array Поддержка полей для JSON …
May 28, 2020, 2:42 p.m.

Django - Tutorial 011. Adding comments to the site based on Django

а в чем явное преимущество postgresql над mysql?)
Now discuss on the forum
May 29, 2020, 1:55 a.m.
Igor' Poroshin

QTablwView + QSqlQueryModel скрыть пустой столбец

Да, понятно. В данном случае лучше использовать серверную процедуру (если такие поддерживаются), в которой будет проверяться наличие всех пустых строк у нужного столбца и вызываться соответ…
May 28, 2020, 6:21 p.m.
Rovshan Gurbanov

Сборка под старые версии Android

У меня SDK почти все версии есть, NDK есть версии 10, 17, 21. Но собирается приложение только с NDK v21 под Android версии 7.0 и выше Версия Qt у меня 5.14.2
May 28, 2020, 7:58 a.m.
Evgenij Legotskoj

Освобождение памяти QMainWindow::setCentralWidget

Да, соглашусь. Просто удаление происходит позже, а не сразу.
May 28, 2020, 5:43 a.m.

При подключении к git как указать пароль?

Нужно сделать ssh-keygen и потом полученый из файла код скопировать в ssh ключ в бикбакете
May 28, 2020, 1:42 a.m.


Да, проблема ушла, спасибо.
© EVILEG 2015-2020
Recommend hosting TIMEWEB