Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Parent-Child Relationship



  • Dear all,

    I am trying to understand the basics behind parent-child relationship.

    Sample1:

    ChildWidget::ChildWidget(QWidget *parent)
    {
         // child UI
    }
    ParentWidget::ParentWidget(QWidget *parent)
    {
       // creates parent UI
    }
    void ParentWidget::buttonClicked()
    {
        // create child UI
        childUI = new ChildWidget(this);
        childUI->show();
    
        // connect signal of child to the slot in parent
        connect( childUI
                       , SIGNAL( closeSignal() )
                       , this
                       , SLOT( onCloseChild() ) );
    

    When I press a button, childUI comes up. This is like a popup, which would be shown up on the parent.

    I am trying to hide the parent when the child is being shown

    Sample2:

    ChildWidget::ChildWidget(QWidget *parent)
    {
         // child UI
    }
    ParentWidget::ParentWidget(QWidget *parent)
    {
       // creates parent UI
    }
    void ParentWidget::buttonClicked()
    {
        // create child UI
        childUI = new ChildWidget(this);
    
         this->hide();
        childUI->show();
    
        // connect signal of child to the slot in parent
        connect( childUI
                       , SIGNAL( closeSignal() )
                       , this
                       , SLOT( onCloseChild() ) );
    

    In this case, application crashes at childUI->show();

    If parent is hidden, can't I call show of child?
    Even though the implementation just sets the visibility status?

    Sample3:

    ChildWidget::ChildWidget(QWidget *parent)
    {
         // child UI
    }
    ParentWidget::ParentWidget(QWidget *parent)
    {
       // creates parent UI
    }
    void ParentWidget::buttonClicked()
    {
        // create child UI
        childUI = new ChildWidget(this);
    
        //childUI->show();
    
        // connect signal of child to the slot in parent
        connect( childUI
                       , SIGNAL( closeSignal() )
                       , this
                       , SLOT( onCloseChild() ) );
    

    If I don't call, child->show(), then signal-slot connection fails with the error
    (null)::closeSignal failed

    Can you please let me know why Sample 2 and Sample 3 fails?

    Thank you!

    Regards,
    Kumara


  • Moderators

    @kumararajas
    I take a wilde guess here and say parent widget and child widget are the only visible widgets of your application ? And you did not quitOnLastWindowClosed to false ?

    https://doc.qt.io/qt-5/qguiapplication.html#quitOnLastWindowClosed-prop



  • @J-Hilk There are many other widgets as well

    ParentWidget that i have mentioned is one widget of the application. There are other widgets too. I haven't used quitOnLastWindowClosed in my application.


  • Lifetime Qt Champion

    Hi,

    If your parent widget is the only one shown and you hide it before showing your child widget, then the application will stop because there's no more widgets to show therefore deletion will happen.



  • @SGaist
    Example, here is how UI is designed

    State 1

    |-------------------|
    |      W1           |
    |-------------------|
    |       W2          |
    |-------------------|
    |              Open |
    |       W3          |
    |                   |
    |-------------------|
    

    W1 & W2 are the other widgets
    W3 has a open button which would bring up the child widget W31.

    After clicking on the Open button

    State 2

    |-------------------|
    |      W1           |
    |-------------------|
    |       W2          |
    |-------------------|
    |                 X |
    |       W31         |
    |                   |
    |-------------------|
    

    W31 has some details to be shown to the user. On pressing X button button, UI would go back to State 1.

    In this scenario, When Open button is clicked, I want to hide W3 and show W31.

    As I have mentioned above, when I call W3 hide, W31 's show crashes the application.


  • Lifetime Qt Champion

    Wouldn't it make more sense to use a QStackedWidget ?



  • @SGaist Not thought about it. But, this is more like a pop-up widget comes up when clicking on 'open' and gets closed when we close it.


  • Lifetime Qt Champion

    Ok, so since it's a popup, why hide the other widget ?



  • @SGaist That's a good point Sam. Actually, I don't need to hide the parent, when the child is being shown.
    It was an attempt to understand if I can hide the parent when the child is being shown.

    Looks like we can't hide the parent when the child is being shown. I was trying to understand the reason and how Qt handles it.


  • Moderators

    @kumararajas said in Parent-Child Relationship:

    Looks like we can't hide the parent when the child is being shown

    You should be able to, when you hide the parent, after the child is actually shown



  • @J-Hilk

    void ParentWidget::buttonClicked()
    {
        // create child UI
        childUI = new ChildWidget(this);
    
         this->hide();
        childUI->show();
    }
    

    In the code snippet that I have mentioned above,
    After this->hide which hides the parent, child->show does not bring up the child UI. When I print the visibility state, it returns false


  • Moderators

    @kumararajas said in Parent-Child Relationship:

    In the code snippet that I have mentioned above,
    After this->hide which hides the parent, child->show does not bring up the child UI. When I print the visibility state, it returns false

    I said, show it first, then hide it

    void ParentWidget::buttonClicked()
    {
        // create child UI
        childUI = new ChildWidget(this);
    
        childUI->show();
        this->hide();
    }
    

    actually now that I read that, IIRC then the parent propagates the hide event to all it's (widget) children 🤔
    So it shouldn't work


    void ParentWidget::buttonClicked()
    {
        // create child UI
        childUI = new ChildWidget(this);
    
        childUI-> setWindowModality(Qt::ApplicationModal);
        childUI->show();
        this->hide();
    }
    

    could work,
    however, I haven't yet tested it



  • @J-Hilk said in Parent-Child Relationship:

    childUI-> setWindowModality(Qt::ApplicationModal);

    I shall test and keep you posted with the results. Thank you.



  • @J-Hilk @SGaist I have moved on with Sam's approach on why to hide the parent widget when it is being a pop-up. It worked for me, I couldn't test the windowModality.

    Thank you for the help.

    --Kumara


Log in to reply