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

Qt: parent-child widgets. Does closing of a single child widget imply closing of other children (siblings)?



  • I have the following problem with the test Qt application, which contains one parent widget and two child widgets, which are separate windows. If the parent widget is hidden, then closing a single child widget implies closing the second child as well as closing the whole application.

    Is it the normal behavior of the parent/child widgets in Qt? Is there a way to keep the second child widget visible and the application running?

    #include <QApplication>
    #include <QtWidgets>
    
    class MyWidget : public QWidget {
    public:
        MyWidget(const QString& title = "", QWidget *parent = nullptr) :
            QWidget(parent) {
            setWindowTitle(title);
            setWindowFlags(windowFlags() | Qt::Window);
            setVisible(true);        
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MyWidget parent("Parent");
        MyWidget *child1 = new MyWidget("Child1", &parent);
        MyWidget *child2 = new MyWidget("Child2", &parent);
        QTimer::singleShot(5000, [&](){parent.hide();});
    
        return a.exec();
    }
    

    There're three widgets of simple class MyWidget: the parent one 'parent' with two childs 'child1' and 'child2'. After 5 sec the parent widget is hidden by the QTimer::singleShot. After that, if I close, e.g. child1 window, the second window child2 is also automatically closed and the application is finished.

    I'd expect that child1 and child2 are independent, and closing one of them shouldn't close another one.


  • Moderators

    @BorysL
    why creating a parent-child relationship then in the first place?
    If it is just for automatic deletion upon closing you can set set Qt::WA_DeleteOnClose widget attribute, or hold a pointer to the child widget and delete the child widget manually, but don't add it to the parent-child hierarchy.



  • @raven-worx Actually, because the parent-child relationship theoretically :)) should be simpler. It's not necessary to worry about the memory leaks, about delete vs deleteLater :) things.



  • I'm about to investigate something akin to this in my code next week.

    I'm surprised that that hiding the parent causes the application to close (and only do so when one child is closed while the other is still open). Are you sure about this? Could any Qt expert explain why the application would be exited in this circumstance, because I cannot see why that would be?


  • Moderators

    @JonB said in Qt: parent-child widgets. Does closing of a single child widget imply closing of other children (siblings)?:

    I'm surprised that that hiding the parent causes the application to close (and only do so when one child is closed while the other is still open). Are you sure about this?

    the question was that the parent got closed after some time which also closes the children. When all windows are closed the application quits.
    If you do not want this behavior, set the QGuiApplication::quitOnLastWindowClosed property accordingly.



  • @raven-worx
    QTimer::singleShot(5000, [&](){parent.hide();});

    The parent does not get close()d, it gets hide()den. Looking at the docs I'm not clear how hide is related to close, could you explain?

    [Background: in someone else's code I have to return to next work, he is hide()ing parent, not close()ing. I'm seeing different behaviour under my Linux vs his Windows (which I don't have) in just this situation (parent hiding, not closing). So I'd like to understand, I may have to raise my own query on this. Thanks.]



  • @raven-worx
    In a distinct issue (separate post by me here, as I'd like it if you kindly answered my post above separately), your answer does not address the behaviour the user claims. You say

    parent got closed after some time which also closes the children

    but the OP reports that after parent closure the app does not exit. He says:

    After 5 sec the parent widget is hidden by the QTimer::singleShot. After that [my italics], if I close, e.g. child1 window, the second window child2 is also automatically closed and the application is finished

    so app having two separate open child widgets only exits when one of them is later closed --- what's going on here?


  • Qt Champions 2019

    hide() doesn't trigger the check if the last window was closed - only close (as the wording suggests).
    When you the close the child, the close check is triggered and since there is no toplevel widget the application quits.


  • Moderators

    @JonB said in Qt: parent-child widgets. Does closing of a single child widget imply closing of other children (siblings)?:

    so app having two separate open child widgets only exits when one of them is later closed --- what's going on here?

    hard to say, my guess is you implicitly/unintentionally connected them somehow



  • @Christian-Ehrlicher

    and since there is no toplevel widget the application quits

    But there is a top-level widget (OP's MyWidget parent). It just happens to have been subjected to hide(), but not to close(). Does your statement mean there is no visible top-level widget so the app closes? I thought the windows system (e.g. Windows) has a distinction between hiding vs closing a window (e.g. IIRC ShowWindow(hWnd, SW_HIDE) is not the same thing as CloseWindow(hWnd))?



  • @raven-worx

    my guess is you implicitly/unintentionally connected them somehow

    I can only say that I took the OP's code shown as complete code, hence his question, there are no connections.


  • Qt Champions 2019

    @JonB said in Qt: parent-child widgets. Does closing of a single child widget imply closing of other children (siblings)?:

    visible top-level widget

    Yes - that's the check - if no tlw is visible setQuitOnLastWindowClsoed jumps in.



  • @Christian-Ehrlicher
    Thanks, Christian. OK then there is still some conflabration over "hiding" vs "closing". I thought they were distinct concepts, it seems they are being treated as the same sort of thing. Maybe my understanding is wrong and they are the same thing.


  • Qt Champions 2019

    close() does a little bit more than hide() - first you can intercept it in closeEvent(), than it deletes the window when Qt::WA_DeleteOnClose is set and afterwards it checks for deleteOnClose: https://doc.qt.io/qt-5/qwidget.html#close


Log in to reply