Important: Please read the Qt Code of Conduct -

Integrating QML and C++ problem

  • I do as described in the tutorial:

    I am writing a simple logger transmitting messages from within the program to the text area of the application.:

    #ifndef LOGGER_H
    #define LOGGER_H
    #include <QObject>
    class Logger : public QObject
        Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged)
        explicit Logger(QObject *parent = nullptr);
        void messageChanged();
        QString message() const;
        Logger& operator << (QString value);
        void setMessage(const QString& value);
        QString log_message;
    #endif // LOGGER_H


    #include "include/logger.h"
    Logger::Logger(QObject *parent) : QObject(parent)
    QString Logger::message() const
        return log_message;
    Logger& Logger::operator << (QString value)
        return *this;
    void Logger::setMessage(const QString& value)
        if (log_message != value) {
            log_message = value;
            emit messageChanged();


    qmlRegisterType<Logger>("edu.logger", 0, 1, "Logger");

    And trying to get the value in the form.

    Logger {
         id: log;
         onMessageChanged: logWidget.append(log.message)  <------- This does not work
    TextArea {
         id: logWidget
         placeholderText: qsTr("Clear log")
         text: log.message        <------- It works

    For some reason, onMessageChanged event does not occur. There are no error messages, variables are changing.

  • Moderators

    @Alexey-Moiseev said in Integrating QML and C++ problem:

    text: log.getLastMessage <------- It works

    How? There is no getLastMessage property in your Logger class!

    How do you call your setMessage() method or modify message property?

  • @sierdzio Sorry, too many versions of the same I wrote too. Mixed when inserted. Fixed the code in the initial post. Existing functions are called.
    I call setMessage from an overloaded operator "<<", where setMessage changes the variable. If you display the values through qDebug, then you can see that the values come and change. But the signal does not call. As I pointed out in the code, when log.message is called separately, it works. But the onMessageChanged event does not occur.

  • Moderators

    That's weird. I can think of only 3 explanations:

    • you're trying to log the same message, so if (log_message != value) { condition is not met, and signal is not emitted (BTW. it's quite bizarre to have a logger which prevents the same message from being logged twice!)
    • TextArea.append() somehow does not work... but that's unlikely. Or maybe text is added below your viewport? append() adds a newline so you might miss it if your UI is small
    • log.message does not return correct value when invoked in a slot... but that's unlikely

    One possible solution: pass message as argument in messageChanged(const QString &msg) signal, then use it in slot onMessageChanged: logWidget.append(msg).

  • Why did the question get downvoted? This isn't SO.

  • @sierdzio

    1. That was the first thing I checked.
    2. The text is inserted where necessary, it works:
    TextArea {
         text: log.message
    1. log.message returns the correct value, because № 2.
    2. This solution was the second that I tried.

  • Moderators


    can you check the following? Maybe append is the issue here.

    Logger {
    id: log;
    onMessageChanged: logWidget.append(log.message) <------- This does not work
    onMessageChanged: logWidget.text = log.message <------- Does this work ?

  • @J-Hilk No. Like any other action written in onMessageChanged. For some reason, onMessageChanged is not called. I also can’t check the emit function call, because it's void.

  • Moderators

    @Alexey-Moiseev and when you simply print something to the console ?

    onMessageChanged:console.log("onMessageChanged", log.message)

Log in to reply