Unsolved How to access ui in other class
-
Hi !
I know that it has been debated many and many times on the web.
But for sure it doesn't seem very clear what the best approach is.Some times we speak about passing the ui pointer, or we speak about Slots.
I have the application class including the ui and other classes A, B, C ...
How can I use ui in A, B, C ?
The application class cpp includes the headers for A, B, C ...Thanks
-
I don't know the better/high efficiency solution. But you can achieve this using the signal and slot method.
Here in this example made by me. I have two classes , one with the Mainwindow and other with the Dialog. The Dialog class takes the the text from the linedit, which is in Mainwindow_ui. -
@Ni.Sumi Thank you. I'll take a look
-
@Ni.Sumi Well. I took a look and it seems easy to understand.
Mainwindow.cpp includes mainwindowsecond. h and mainwindowsecond obviously includes mainwindow.h. That's exactly bored me but there is no other solution to do it.
I think this solution is better than passing a pointer because it keeps encapsulation.
Thank you again. -
Usually when you think about accessing
ui
member of another class it means your classes structure is not well thought out and you're looking for quick workarounds.The
ui
member is considered private implementation detail of the class that has it. Other classes should not access it directly like they shouldn't access any other private member.
If you want to expose some of the generated widgets you create a public getter/setter functions for it, but it's usually also not a good idea, as it indicates bad class design.
What you really want is a set of slots that will mediate in accessing the ui.For example lets say you have class
Clock
that has a label that displays time. Now consider these 3 designs if you wanted to set the time. First we'll do it lazily and just make ui member public:Clock clock; clock.ui->label->setText(QTime::currentTime().toString(Qt::SystemLocaleDate));
Yuck! That's terrible. Let's try to expose only the label via some getter function:
Clock clock; clock.getLabel()->setText(QTime::currentTime().toString(Qt::SystemLocaleDate));
Still messy... Now let's make it right and create a dedicated slot that will take care of formatting and access the ui:
Clock clock; clock.setTime(QTime::currentTime()); //could also emit timeChanged() signal for example
Ahh, much better. Now you can change the implementation of the clock, switch label to some other widget etc. and the interface doesn't change. That's the clean design Qt uses for its classes and one that you should aim for.
-
@Chris-Kawa Thanks for this Explanation !
-
@Chris-Kawa I am trying to implement these principles.
I have the application class including members and I have the database class that has to modify a member of the application class.
I defiined a SIGNAL in the class database called signalSetMember(const QString arg)
Now in the database class, I have to connect this SIGNAL to a SLOT in the application class. So I need a pointer of the class application in the class database.
How do I get it ?Thanks
-
@mulfycrowh Who is creating what? If the application class creates database class instance, then it can connect signals/slots. Else you can pass the application pointer/reference to database constructor.
-
@jsulm I wrote this and it compiles:
connect(this, &Application::signalSetScoreReference, m_db, &Score::setScoreReference);
Application is the class for application,
m_db is the pointer to class Database,
signalSetScoreReference is the SIGNAL in Application
setScoreReference is the SLOT in DatabaseTo make it compile I added that Database inherit from QQbject.
Is it OK ?
-
@mulfycrowh Looks fine. For signals/slots to work you have to inherit from QObject and add Q_OBJECT makro just at the beginning of your class:
#include <QObject> class Counter : public QObject { Q_OBJECT
-
@jsulm thanks and public inheritance from QObject is very important to match connect