How to close all the open dialog boxes or toplevel QWidgets when QMainWindow is close



  • When I click on close X (close sign at the top right corner ) or close the main window using QMainWindow->close() . I want to close all the opened dialogboxes and open top level QWidgets . Looking at documentation I can see we have http://doc.qt.io/qt-5/qapplication.html#closeAllWindows QApplication::closeAllWindows().
    As I understand < I have write code like this
    class MyMainWindow:public QMainWindow {

    }

    void MyMainWindow.closeEvent(QCloseEvent *event)
    {
    QApplication::closeAllWindows()
    QMainWindow.closeEvent(event);
    }

    Also does this closeEvent also gets called when when QMainWindow::close method is called


  • Lifetime Qt Champion

    Hi,

    Yes, sending of the close event is the first thing done. It's described in the method documentation.



  • My GUI hangs when click on X mark on top right and if I use following code

    class MyMainWindow:public QMainWindow {

    }

    void MyMainWindow.closeEvent(QCloseEvent *event)
    {
    QApplication::closeAllWindows()
    QMainWindow.closeEvent(event);
    }


  • Lifetime Qt Champion

    Hi

    ** WRONG ** skip post

    You make infinite loop

    void MyMainWindow.closeEvent(QCloseEvent *event)
    {
    QApplication::closeAllWindows();
    QMainWindow.closeEvent(event); <<< call same again, and again, and again

    maybe just call
    QMainWindow.close() ?


  • Qt Champions 2017

    @mrjj said:

    QMainWindow.closeEvent(event); <<< call same again, and again, and again

    Delegating to the parent class doesn't create a loop.

    @Qt-Enthusiast

    QApplication::closeAllWindows(); probably calls your MyMainWindow::closeEvent again, and then again ...

    Try something like:

    void MyMainWindow::closeEvent(QCloseEvent * event)
    {
        foreach (QWidget * widget, QApplication::topLevelWidgets())  {
            if (widget == this)
                continue;
            widget->close();
        }
        event->accept();
    }
    
    

  • Lifetime Qt Champion

    Sorry my bad
    saw it as . not ::

    More coffee for me :)


  • Qt Champions 2017

    @mrjj

    More coffee for me :)

    More coffee is always a good idea, anytime, I've found out ... :D



  • Thanks what does event->accept do in following code. and why it is required because I tried without event -accept , it is working

    void MyMainWindow::closeEvent(QCloseEvent * event)
    {
    foreach (QWidget * widget, QApplication::topLevelWidgets()) {
    if (widget == this)
    continue;
    widget->close();
    }
    event->accept();
    }


  • Qt Champions 2017

    @Qt-Enthusiast
    QEvent::accept tells Qt that you accept the event (i.e. you have processed it). In this particular case it notifies the framework that you accept your window to be closed (if you call event->ignore()) the window will not be closed.



  • @kshegunov said:

    ou call event->i

    What if we dont put this line event->accept than any side effects of the same


  • Qt Champions 2017

    @Qt-Enthusiast

    What if we dont put this line event->accept than any side effects of the same

    If I recall correctly, the event will be propagated to the parent widget. Since you don't have a parent widget, there shouldn't be any side effects. Still, it's a good habit to either accept/ignore events you're processing, or to delegate processing to the parent class.



  • One more thing , I am declaring this method closeEvent as public in class MyMainWindow:QMainWindow {
    public:
    closeEvent(QCloseEvent*);
    }

    In some forums I was seeing closeEvent as protected , Why it is so


  • Qt Champions 2017

    @Qt-Enthusiast
    It should be protected in principle, but since overriding virtual functions care not for the access modifiers (overriding basically changes an address used internally in the virtual table) making it public is not an error (at least not a syntax one). My advice is to follow Qt's documentation's access and use protected.


  • Lifetime Qt Champion

    It's protected by design because it's not a function that an external class should call. However, subclasses can modify it in order to accommodate it to their needs. Therefore as @kshegunov suggested, keep it protected.



  • Also one more question do we need to call following line QMainWindow::closeEvent(event) like in the following code if yes why

    void MyMainWindow::closeEvent(QCloseEvent * event)
    {
    foreach (QWidget * widget, QApplication::topLevelWidgets()) {
    if (widget == this)
    continue;
    widget->close();
    }
    event->accept();
    QMainWindow::closeEvent(event)
    }


  • Qt Champions 2017

    @Qt-Enthusiast said:

    do we need to call following line QMainWindow::closeEvent(event)

    No, you don't need to call it. It's the main window's implementation which by default (if I'm not mistaken) just accepts the event.


  • Lifetime Qt Champion

    It ends up calling QWidget's closeEvent which indeed just accepts the event. However, it's still a good habit to call the base class implementation since it might change in the future and do other useful stuff that would be lost otherwise.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.