How to Integrate spdlog with Qt Applications Using qt_color_logger

Use spdlog::qt_color_logger_mt() or qt_color_logger_st() to create a threaded logger that writes color-coded log messages directly to any QTextEdit-based widget.

Integrating spdlog with Qt applications using qt_color_logger gives you fast, thread-safe logging with automatic color formatting inside your GUI. The qt_color_sink in spdlog intercepts color range markers from your log pattern and translates them into QTextCharFormat styling for each log level.

Include the Qt Sink Header

The Qt sinks live in include/spdlog/sinks/qt_sinks.h. This header defines:

  • qt_color_sink – the actual sink implementation
  • qt_sink – a plain-text variant without colors
  • Factory functions: qt_logger_mt, qt_logger_st, qt_color_logger_mt, qt_color_logger_st

Source: [spdlog/sinks/qt_sinks.h](https://github.com/gabime/spdlog/blob/v1.x/include/spdlog/sinks/qt_sinks.h#L291-L304)

Include this header alongside your Qt headers:

#include <QTextEdit>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/qt_sinks.h"

Create a Color Logger

Call qt_color_logger_mt() for multi-threaded use or qt_color_logger_st() for single-threaded contexts. Pass your target widget and a maximum line count:

QTextEdit *logWidget = new QTextEdit();
logWidget->setReadOnly(true);

auto logger = spdlog::qt_color_logger_mt("qt_logger", logWidget, /*max_lines=*/200);

Critical: The widget must outlive the logger, or you must ensure a permanent QObject parent exists. The sink holds a reference to the widget and warns about dangling references in the source comments at qt_sinks.h#L10-L13.

Enable Color Ranges in Your Pattern

The sink extracts color indices from log_msg ranges. Activate them with %^ (start color) and %$ (reset) in your pattern:

spdlog::set_pattern("%^[%T] [%l] %v%$");

Without these markers, no color ranges are generated and the output appears in default styling.

Complete Working Example

#include <QApplication>
#include <QTextEdit>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/qt_sinks.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    
    QTextEdit *logWidget = new QTextEdit();
    logWidget->setReadOnly(true);
    logWidget->show();

    // Create multithreaded color logger limited to 200 lines
    auto logger = spdlog::qt_color_logger_mt("qt_ui", logWidget, 200);
    
    spdlog::set_pattern("%^[%T] [%l] %v%$");
    spdlog::set_default_logger(logger);

    logger->info("Application started");
    logger->debug("Loading configuration...");
    logger->warn("Config file missing, using defaults");
    logger->error("Failed to open database: {}", "connection refused");
    logger->critical("Unrecoverable error");

    return app.exec();
}

Customize Log Level Colors

Retrieve the underlying sink to override the default color palette:

auto sink = static_cast<spdlog::sinks::qt_color_sink<std::mutex> *>(
                logger->sinks().front().get());

// Custom warning color
QTextCharFormat warnFormat;
warnFormat.setForeground(Qt::magenta);
sink->set_level_color(spdlog::level::warn, warnFormat);

// Custom default color for unspecified levels
QTextCharFormat defaultFormat;
defaultFormat.setForeground(Qt::darkGray);
sink->set_default_color(defaultFormat);

Alternative: Plain Text Without Colors

For uncolored output, use qt_logger_mt() or qt_logger_st(). These require a slot name to receive QString messages:

auto plainLogger = spdlog::qt_logger_mt("plain", logWidget, "append");
plainLogger->info("Plain text log entry");

The slot "append" (or your custom slot) receives formatted messages as QString.

Build Configuration

No additional dependencies beyond Qt itself. Ensure Qt development headers are available when building spdlog. In CMake:

find_package(Qt6 REQUIRED COMPONENTS Core Widgets)
target_link_libraries(myapp PRIVATE Qt6::Core Qt6::Widgets spdlog::spdlog)

The Qt sink is header-only; no special compile definitions are required unless using external format libraries.

Summary

  • Include spdlog/sinks/qt_sinks.h to access spdlog Qt integration
  • Use qt_color_logger_mt() or qt_color_logger_st() for color-coded Qt logging
  • Enable colors with %^...%$ pattern markers
  • Ensure the target QTextEdit outlives the logger to prevent dangling references
  • Customize colors via set_level_color() and set_default_color()
  • Use qt_logger_mt() for plain-text output without color processing

Frequently Asked Questions

What Qt widget types work with qt_color_logger?

Any subclass of QTextEdit works: QTextEdit, QPlainTextEdit, or QTextBrowser. The sink writes formatted text through QTextCursor operations and applies QTextCharFormat for color ranges.

Is qt_color_logger thread-safe?

Use qt_color_logger_mt() for thread-safe operation. The _mt suffix indicates std::mutex protection for concurrent logging from multiple threads. Use qt_color_logger_st() only when all logging originates from the same thread.

Why are my log messages not colored?

Verify your pattern includes %^ and %$ markers. Without these, spdlog's formatter generates no color ranges, and the sink has no color information to apply. Example: "%^[%T] %l: %v%$".

Can I use spdlog with Qt without the qt_color_logger helper?

Yes. Instantiate spdlog::sinks::qt_color_sink directly and add it to any spdlog::logger. The helper functions merely wrap this construction for convenience.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →