Proper way to update widget from other class
-
Hello everyone!
I'm stuck with the problem, so: i have a form that have input widget and i want to update that widget from another class:Here is the form:
H-file#pragma once #include <QtWidgets/QMainWindow> #include "ui_QtWidgetsApplication1.h" #include "test_class.h" class QtWidgetsApplication1 : public QMainWindow { Q_OBJECT Ui::QtWidgetsApplication1Class ui; public: QtWidgetsApplication1(QWidget* parent = Q_NULLPTR); public slots: void updateText(const QString& text); };
CPP-file
#include "QtWidgetsApplication1.h" #include "test_class.h" QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); } void QtWidgetsApplication1::updateText(const QString& text) { ui.plainTextEdit->appendPlainText(text); }
And class from within i need to update a widget:
H-file#pragma once #include <QObject> #include "QtWidgetsApplication1.h" class Counter : public QObject { public: Counter() { connect(); } void connect(); signals: void sendText(const QString& newText); private: Q_OBJECT; };
and CPP-file
#include "test_class.h" #include <QObject> #include "QtWidgetsApplication1.h" void Counter::connect() { emit sendText("WOW"); }
Main CPP
#include "QtWidgetsApplication1.h" #include <QtWidgets/QApplication> #include "test_class.h" #include <QObject> int main(int argc, char *argv[]) { QApplication a(argc, argv); QtWidgetsApplication1 w; w.show(); return a.exec(); }
I'll try to connect it in form class like
Counter c; connect(&c, SIGNAL(sendText()), this, SLOT(updateText())); // or connect(&c, Counter::sendText, this, QtWidgetsApplication1::updateText);
It doesn't work
But if i instantiate connect in main, like this:
... QtWidgetsApplication1 w; Counter c; QObject::connect(&c, &Counter::sendText, &w, &QtWidgetsApplication1::updateText); // and then assign c.sendText("No-no-no");
It obviously work.
So the question is how to show up a message "WOW" from Counter::connect() method when program launches.
That's just an example what i want to do.
I use a Qt6.0.1 with VS 2019 win 10 if that matter. -
Since you can't use signals and slots you can for example set a callback function in Counter which gets executed every time you want to send a signal from Counter to Qt. This callback function can then emit a Qt signal.
-
Since you can't use signals and slots you can for example set a callback function in Counter which gets executed every time you want to send a signal from Counter to Qt. This callback function can then emit a Qt signal.
@Christian-Ehrlicher said in Update widget from nonQT class (signal & slot problem):
Since you can't use signals and slots you can for example set a callback function in Counter which gets executed every time you want to send a signal from Counter to Qt. This callback function can then emit a Qt signal.
Can you give me an example? I'm not clearly understand. I thought it's a common usage: i have isolated class with form and UI stuff and some other classes that connected with that form thru some method's. And i thought slots and signals implemented that routine.
That what i'm trying to do is weird? And if it's does can you have a better workaround? -
@hills said in Update widget from nonQT class (signal & slot problem):
I thought it's a common usage:
Emitting a signal from a n object which is not derived from QObject is not common usage. So either derive from QObject or use a callback function.
-
Hi and welcome to devnet,
If I may, adding a "connect" method to a QObject subclass is not really a good idea. You might want to consider a more accurate name.
That said, you do not call said method in your code, hence "WOW" will never be shown.
On a side note, signals should only be called from within the class that defines them.
-
@hills said in Update widget from nonQT class (signal & slot problem):
I thought it's a common usage:
Emitting a signal from a n object which is not derived from QObject is not common usage. So either derive from QObject or use a callback function.
@SGaist said in Update widget from nonQT class (signal & slot problem):
If I may, adding a "connect" method to a QObject subclass is not really a good idea. You might want to consider a more accurate name.
Thanks!
It just an example, for real: i have CLI-based class that has function's with many std::cout log messages inside and i want to translate them into input widgets .@Christian-Ehrlicher said in Update widget from nonQT class (signal & slot problem):
@hills said in Update widget from nonQT class (signal & slot problem):
I thought it's a common usage:
Emitting a signal from a n object which is not derived from QObject is not common usage. So either derive from QObject or use a callback function.
So, i trying to realize callback function, but it fails on QtWidgetsApplication1::UpdateText (error C2228: left of '.textEdit' must have class/struct/union).
How to make this works?FORM H
class QtWidgetsApplication1 : public QMainWindow { Q_OBJECT Ui::QtWidgetsApplication1Class ui; static void updateText(const QString& text); public: explicit QtWidgetsApplication1(QWidget* parent = Q_NULLPTR); };
FORM CPP
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); Counter* c = new Counter(); c->setCallbackFunc(updateText); } void QtWidgetsApplication1::updateText(const QString& text) { ui.textEdit->setText(text); // error C2228: ui.plainTextEdit->appendPlainText(text); // left of '.textEdit' must have class/struct/union }
Counter H
class Counter : public QMainWindow { public: explicit Counter(QObject* parent = 0) { connect(); } void setCallbackFunc(void (*func) (const QString& text)); void connect(); private: void (*callbackFunc)(const QString& text); Q_OBJECT; };
Counter CPP
void Counter::setCallbackFunc(void(*func)(const QString& text)) { callbackFunc = func; } void Counter::connect() { //QString text = "Maybe-maybe"; //callbackFunc(text); callbackFunc("WOW"); }
-
Hi
When you say nonQT class, we think of class that does not inherit QObject
but in your code shown, it does ! `?so if the real issues were
Counter c;
connect(&c, Counter::sendText, this, QtWidgetsApplication1::updateText);only works in main.cpp,
i was wondering if your actual issue was just the use of a local variable that will
get deleted as soon as the function ends. ( the variable c has a short life span if in a function)So maybe the real fix would have been
Counter * c = new Counter (this);
connect(c, Counter::sendText, this, QtWidgetsApplication1::updateText); -
Hi
When you say nonQT class, we think of class that does not inherit QObject
but in your code shown, it does ! `?so if the real issues were
Counter c;
connect(&c, Counter::sendText, this, QtWidgetsApplication1::updateText);only works in main.cpp,
i was wondering if your actual issue was just the use of a local variable that will
get deleted as soon as the function ends. ( the variable c has a short life span if in a function)So maybe the real fix would have been
Counter * c = new Counter (this);
connect(c, Counter::sendText, this, QtWidgetsApplication1::updateText);@mrjj said in Update widget from nonQT class (signal & slot problem):
Hi
When you say nonQT class, we think of class that does not inherit QObject
but in your code shown, it does ! `?so if the real issues were
Counter c;
connect(&c, Counter::sendText, this, QtWidgetsApplication1::updateText);only works in main.cpp,
i was wondering if your actual issue was just the use of a local variable that will
get deleted as soon as the function ends. ( the variable c has a short life span if in a function)So maybe the real fix would have been
Counter * c = new Counter (this);
connect(c, Counter::sendText, this, QtWidgetsApplication1::updateText);Hello!
Unfortunately it didn't work. Fail with error:
error C3867: 'Counter::sendText': non-standard syntax; use '&' to create a pointer to member
error C3867: 'QtWidgetsApplication1::updateText': non-standard syntax; use '&' to create a pointer to member
And if i add &connect(c, &Counter::sendText, this, &QtWidgetsApplication1::updateText);
It compiles without errors and warnings but nothing happened at text widget
-
@mrjj said in Update widget from nonQT class (signal & slot problem):
Hi
When you say nonQT class, we think of class that does not inherit QObject
but in your code shown, it does ! `?so if the real issues were
Counter c;
connect(&c, Counter::sendText, this, QtWidgetsApplication1::updateText);only works in main.cpp,
i was wondering if your actual issue was just the use of a local variable that will
get deleted as soon as the function ends. ( the variable c has a short life span if in a function)So maybe the real fix would have been
Counter * c = new Counter (this);
connect(c, Counter::sendText, this, QtWidgetsApplication1::updateText);Hello!
Unfortunately it didn't work. Fail with error:
error C3867: 'Counter::sendText': non-standard syntax; use '&' to create a pointer to member
error C3867: 'QtWidgetsApplication1::updateText': non-standard syntax; use '&' to create a pointer to member
And if i add &connect(c, &Counter::sendText, this, &QtWidgetsApplication1::updateText);
It compiles without errors and warnings but nothing happened at text widget
@hills said in Update widget from nonQT class (signal & slot problem):
It compiles without errors and warnings but nothing happened at text widget
Are you sure you call sendText() and updateText() is actually doing something? Please add some debug output and make sure the correct instance of Counter is connected.
And please change the title of your question - it's irritating.
-
@mrjj said in Update widget from nonQT class (signal & slot problem):
Hi
When you say nonQT class, we think of class that does not inherit QObject
but in your code shown, it does ! `?so if the real issues were
Counter c;
connect(&c, Counter::sendText, this, QtWidgetsApplication1::updateText);only works in main.cpp,
i was wondering if your actual issue was just the use of a local variable that will
get deleted as soon as the function ends. ( the variable c has a short life span if in a function)So maybe the real fix would have been
Counter * c = new Counter (this);
connect(c, Counter::sendText, this, QtWidgetsApplication1::updateText);Hello!
Unfortunately it didn't work. Fail with error:
error C3867: 'Counter::sendText': non-standard syntax; use '&' to create a pointer to member
error C3867: 'QtWidgetsApplication1::updateText': non-standard syntax; use '&' to create a pointer to member
And if i add &connect(c, &Counter::sendText, this, &QtWidgetsApplication1::updateText);
It compiles without errors and warnings but nothing happened at text widget
Hi. well, it has to have &, as we take the address of a member function.
Also, make sure you mean to actually mean create a new Counter variable.
The one you connect with - is the only one connected so if you have other Counters, you created, they
might not been connected.
That can explain why nothing happens if you have code in the slot that should set some text on the screen. -
@hills said in Update widget from nonQT class (signal & slot problem):
It compiles without errors and warnings but nothing happened at text widget
Are you sure you call sendText() and updateText() is actually doing something? Please add some debug output and make sure the correct instance of Counter is connected.
And please change the title of your question - it's irritating.
@Christian-Ehrlicher said in Update widget from nonQT class (signal & slot problem):
@hills said in Update widget from nonQT class (signal & slot problem):
It compiles without errors and warnings but nothing happened at text widget
Are you sure you call sendText() and updateText() is actually doing something? Please add some debug output and make sure the correct instance of Counter is connected.
Yeah, i tested it in main.cpp - from main he works fine
And please change the title of your question - it's irritating.
No problem, that's better?
@mrjj hi! there is only one variable called Counter an it's within QtWidgetsApplication1.cpp
Here the full project, maybe this will clarify something
https://pastebin.com/h0NFXJrP - main.cpp
https://pastebin.com/YHnYZkwp - QtWidgetsApplication1.h
https://pastebin.com/Z45b5uWx - QtWidgetsApplication1.cpp
https://pastebin.com/c502CUjy - QtWidgetsApplication1.ui
https://pastebin.com/BfKCdUdr - test_class.h
https://pastebin.com/WU3ThMu3 - test_class.cpp -
Where do you call Counter::connect(). And no, calling it in the ctor will not work since the connection is done afterwards.
-
Where do you call Counter::connect(). And no, calling it in the ctor will not work since the connection is done afterwards.
@Christian-Ehrlicher said in Proper way to update widget from other class:
Where do you call Counter::connect(). And no, calling it in the ctor will not work since the connection is done afterwards.
Oh, sweet lord, i finally got something... I call the constructor and after that make connection between form and Counter class. That leads to the fact that all messages that were before the connection disappeared.
So i need to re-write my real code, coz i make stuff in the default constructor that show up some messages.
Thanks a lot @Christian-Ehrlicher! -
@Christian-Ehrlicher said in Proper way to update widget from other class:
Where do you call Counter::connect(). And no, calling it in the ctor will not work since the connection is done afterwards.
Oh, sweet lord, i finally got something... I call the constructor and after that make connection between form and Counter class. That leads to the fact that all messages that were before the connection disappeared.
So i need to re-write my real code, coz i make stuff in the default constructor that show up some messages.
Thanks a lot @Christian-Ehrlicher!@hills Glad you found the problem. Please mark the topic as solved then.