Unsolved Integrating QML and C++ problem
-
I do as described in the tutorial: https://doc.qt.io/qt-5/qtqml-cppintegration-topic.html
I am writing a simple logger transmitting messages from within the program to the text area of the application.:
.h#ifndef LOGGER_H #define LOGGER_H #include <QObject> class Logger : public QObject { Q_OBJECT Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged) public: explicit Logger(QObject *parent = nullptr); signals: void messageChanged(); public: QString message() const; Logger& operator << (QString value); void setMessage(const QString& value); private: QString log_message; }; #endif // LOGGER_H
.cpp
#include "include/logger.h" Logger::Logger(QObject *parent) : QObject(parent) { } QString Logger::message() const { return log_message; } Logger& Logger::operator << (QString value) { setMessage(value); return *this; } void Logger::setMessage(const QString& value) { if (log_message != value) { log_message = value; emit messageChanged(); } }
main.cpp
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.
-
@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 modifymessage
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. -
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 smalllog.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 slotonMessageChanged: logWidget.append(msg)
. - you're trying to log the same message, so
-
Why did the question get downvoted? This isn't SO.
-
- That was the first thing I checked.
- The text is inserted where necessary, it works:
TextArea { text: log.message }
- log.message returns the correct value, because № 2.
- This solution was the second that I tried.
-
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.
-
@Alexey-Moiseev and when you simply print something to the console ?
onMessageChanged:console.log("onMessageChanged", log.message)