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?


  • Lifetime Qt Champion

    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 )
    Like

      explicit 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.


  • Lifetime Qt Champion

    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 :)


  • Lifetime Qt Champion

    @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 ?



  • @SGaist

    I got stuck in my idea of skipping the setters and solving the problem with signals & slots, but to do so you have to have access to the destination class of course ;)



  • @mrjj

    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 :) haha

    Ok 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.