Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

this may seem like a very simple question, but I want to dump some data whenever the QMainWindow closes, so I used the following piece of code:

QObject::connect(MainWindow.centralwidget, SIGNAL(destroyed()), this, SLOT(close()));

But this doesn't seem to make it call close(). Am I doing this wrong?.
Isn't the centralwidget suppose to be destroyed?.

Or perhaps the application closes before close() can be called?.

Any other ways of doing it then?

Where does this fit in within your QObject hierarchy? It may be that it's getting deleted before the signal is sent. Of course I wouldn't worry about it too much as there are better alternatives in the answers given so far. – Troubadour Jun 10, 2010 at 17:54 You cant dump data with the code you have shown... Also whether your question is how to dump data before QMainWindow closes? or why QMainwindow is not closing? Do make it clear... – liaK Jun 10, 2010 at 17:57 I want to write and XML file after I click the 'x' to close the main window. It doesnt seem to work with the code above or the QApplication::lastWindowClosed() (or QApplication::aboutToQuit() for the matter)... Havent tried the QCloseEvent, but to keep the MVC structure, I rather not. The class I'm working in isnt the QMainWindow, rather I use files obtained by compiling ui files made in designer. – Cenoc Jun 10, 2010 at 18:09

You better to re implement one virtual function in your main MainWindow class like this:

class MainWindow : public QMainWindow {
    Q_OBJECT;
public:
    MainWindow();
protected:
     void closeEvent(QCloseEvent *event);

and then declare in source file:

void MainWindow::closeEvent(QCloseEvent *event) {
     // do some data saves or something else

Good luck.

It's a good idea to complete the override. IE: in closeEvent() call QMainWindow::closeEvent(event); at the end of the function. See the example in the documentation for the saveState() function here: doc.qt.io/qt-4.8/qmainwindow.html – Ph0t0n Jan 19, 2017 at 20:38 While Ph0t0n isn't necessarily wrong, real-world closeEvent() implementations typically call either event.accept() or event.ignore() depending on whether unsaved changes exist or not. QMainWindow::closeEvent(event) is typically not called. See closeEvent() documentation for yet another useful example. – Cecil Curry Dec 23, 2017 at 8:00 Didn't work, must mean it's being destroyed before that signal can be accepted? But that's odd because the class's destructor doesn't seem to be outputting anything (through std::cerr) – Cenoc Jun 10, 2010 at 18:07 Make sure the object with the slot isn't a child of the QMainWindow. QWidgets destroy all their children when they go down. – György Andrasek Jun 10, 2010 at 18:15 Woops, good catch, it worked! A million thanks! Definitely wouldnt have looked in the QApplication for this. – Cenoc Jun 10, 2010 at 18:19 In Python (pyqt4 or pyqt5) you would need to do the following:

class MyWindow(QMainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()
        # My initializations...
    ''''''
    def closeEvent(self, *args, **kwargs):
        # Stuff I want to do when this
        # just before (!) this window gets closed...
    ''''''

It is interesting to know that the stuff in the closeEvent(..) function gets executed just before  the window closes. You can verify this with the following test:

    # Test if the closeEvent(..) function
    # executes just before or just after the window closes.
    def closeEvent(self, *args, **kwargs):
        # 'self' is the QMainWindow-object.
        print(self)
        print(self.isVisible())
        # Print out the same stuff 2 seconds from now.
        QTimer.singleShot(2000, lambda: print(self))
        QTimer.singleShot(2100, lambda: print(self.isVisible()))
    ''''''

This is the output in your terminal:

<myProj.MyWindow object at 0x000001D3C3B3AAF8>
<myProj.MyWindow object at 0x000001D3C3B3AAF8>
False

This proves that the window was still visible when entering the closeEvent(..) function, but not after exiting that function.

Your initial question and code don't match. If you want to do something on the QMainWindow either create a sub-class and re-implement closeEvent or connect to MainWindow::destroyed(). See the 3rd paragraph for a note however.

But your code is showing what appears to be a 3rd class that is connecting a child of the MainWindow being destroyed to some slot called close(). centralwidget will be destroyed AFTER MainWindow is already destroyed so this most likely won't help you anyway.

Also, this depends on how you created MainWindow (stack or heap) and if you are destructing it properly. Ideally, you should create a subclass of QMainWindow (which if you used the designer you probably already have).

Implement QMainWindow::closeEvent(QCloseEvent *) in your class. Then implement a new signal called closing() and emit it from your implementation of QMainWindow::closeEvent(). Then you can connect to that signal to do something right before the window is closed. You can also use closeEvent directly to do what you need to do, like save state, sync data or whatever.

You can't accesss I/O in destroyed or the destructor of the MainWindow - you are finally in your applications destructor and everything is destroyed. Use closeEvent() instead. – Jens Jun 10, 2010 at 18:15

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.