Access object from multiple UI classes
-
I have the following class structure:
- MainWindow (Parent)
- Window 1 (Child)
- Window 2 (Child)
- Window 3 (Child)
- Non UI class
What is the best way to access the same instance of the non-UI class (class for some calculations)?
The MainWindow-UI and all child UIs should be able to access the setters / getters / slots (via connections) to change settings.Like this:
connect(ui->btn_start, SIGNAL(clicked()), "GET INSTANCE OF CALCUALTION CLASS ", SLOT("SlotInCalculationClass");
I've tried it with parent pointers, but it only grants access to functions inherited from QWidget / QWindow, not to my own slots / setters in this class.
Is the parent-approach in general a bad style of programming? Is it possible to pass the instance with signals / slots from MainWindow to its childs, when they appear?
- MainWindow (Parent)
-
Hi and welcome to the forums.
Using parent pointer is not super bad as such, but its stored in QWidget pointer so you have to cast to own type
to have access to your added members.Windows1 *mywin = qobject_cast<Windows1 *> ( parent ); if (mywin) { // always check if cast didnt fail }
However, it makes a tight coupling between child and parent so
a more clean solution is to
change the child constructors to take a reference or pointer to the Non UI class (the data )
Likeexplicit MyWindow(QWidget *parent = nullptr); to explicit MyWindow(QWidget *parent , MyData * TheData );
and it can then store it locally as a member to be used for what ever it needs.
You just give the Data class with the constructor when you create the child windows.To manage the pointers you give out to child windows, you can use
http://doc.qt.io/qt-5/qsharedpointer.html#details
for automatic reference counting so no pointers could be left dangling in the sub children while
the main one was deleted. -
Hi,
If that calculation class can be changed during the lifetime of your application, you should consider following the model/view classes of Qt and have a
setCalculationObject
setter that will handle the setup and cleanup of the connection to that object. -
@mrjj
Ok thank you.Changing the child's constructor and passing the data would be the same as creating the instance of the class in MainWindow (parent) and then pointing to that object with setters / getters, right?
mainwindow.cpp
// Create instance of MyClass MyClass *m_MyClass = new MyClass (); // Create Childs // .... MainWinChild->setMyClass(m_MyClass);
But inside the constructor seems to be a cleaner solution...
Would declaring my nonUIClass (MyClass in code above) as Singleton do the same?
Is there a way to change member values inside an unknown class from a UI class with signals and slots only?I've tried it nearly every day since start of this project :) My GUI is done and most of the backend logic as well, but I couldn't connect all GUI elements because you have to set a destination for the SLOT :)
-
@Pl45m4 said in Access object from multiple UI classes:
Would declaring my nonUIClass (MyClass in code above) as Singleton do the same?
Hi, yes to some degree but globals in Qt are extra bad as no QOBject should be created
before QApplication is ( in main )
so that is why via constructor is preferred.
That said, the setMyClass way is much the same and also good.- Is there a way to change member values inside an unknown class from a UI class with signals and slots only?
Yes, to some degree. if you have a place where both types are known, and then hook up the signal/slots then
the participating classes do not know the exact type of the other class.
one class will just use emit to trigger the slot in the other classes with no knowledge of the receiver.Im fear i maybe dont understand the full extend of your issue.
Could you explain a bit more what you have and why normal connect with objects pointers is not
enough ? -
If it works with setters, it should be fine.
I'm relatively new to Qt and since you have signals and slots, I thought using setters is maybe not the best way, so there MUST be another solution :) hahaOk I will try it out tomorrow and let you know if it worked for me :)
EDIT:
@mrjj @SGaist
Thank you guys, passing the pointer to my data with constructor and setting the data to a local member to use it inside my WindowChildClass worked for me.