views:

49

answers:

4

I am collecting usage stats for my applications which include how much each session lasts. However, I can't seem to be able to save this information because None Of the signals I tried yet actually succeeds to call my report_session function.

This are the signals I have already tried:

  1. lastWindowClosed()
  2. aboutToQuit()
  3. destroyed()

Either these signals never get emitted or the application does not live long enough after that to run anything else. Here is my main:

app = QtGui.QApplication(sys.argv)

ui = MainWindow()
ui.app = app
QtCore.QObject.connect(ui, QtCore.SIGNAL("destroyed()"),  ui.report_session)
ui.show()
logger.info('Started!')
splash.finish(ui)

sys.exit(app.exec_())
+1  A: 

Put the code between app.exec_ and sys.exit:

ret = app.exec_()
# Your code that must run when the application closes goes here
sys.exit(ret)
Mark Byers
+2  A: 

To ensure that a Python function gets called at process termination, in general (with or without Qt involved;-), you can use the atexit module of the standard Python library:

import atexit

def whatever(): ...

atexit.register(whatever)

Out of prudence I would recommend against using a bound method instead of a function for this purpose -- it "should" work, but the destruction-phase of a process is always somewhat delicate, and the simpler you keep it, the better.

atexit won't trigger for a sufficiently-hard crash of a process, of course (e.g., if the process is killed with a kill -9, then by definition it's not given a chance to run any termination code) -- the OS sees to that;-). If you need to handle any crash no matter how hard you must do so from a separate "watchdog" process, a substantially subtler issue.

Alex Martelli
I haven't tried that, though I was aware of the atexit module. I ended up prefering to reimplement the closeEvent method of QApplication.
fccoelho
A: 

Found this answer which involves overloading closeEvent().

it worked perfectly for me.

fccoelho
+1  A: 

The method that Mark Byers posted will run after the main widget has been closed, meaning that its controls will no longer be available.

If you need to work with any values from controls on your form, you will want to capture the close event and do your work there:

class MainWidget(QtGui.QWidget):

    #...

    def closeEvent(self, event):
        print "closing PyQtTest"
        self.SaveSettings()
        # report_session()

Also, see the Message Box example in the ZetCode tutorial First programs in PyQt4 toolkit (near the end of the page). This shows how to accept or cancel the close request.

Todd