Есть ли способ вызвать функцию прямо перед завершением PyQt-приложения? - PullRequest
6 голосов
/ 30 сентября 2010

Я собираю статистику использования для своих приложений, которая включает продолжительность каждого сеанса.Тем не менее, я не могу сохранить эту информацию, потому что ни один из сигналов, которые я пробовал, на самом деле не вызывает мою функцию report_session.

Это сигналы, которые я уже пробовал:

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

Либо эти сигналы никогда не излучаются, либо приложение не живет достаточно долго, чтобы запустить что-либо еще.Вот мой главный:

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_())

Ответы [ 4 ]

5 голосов
/ 30 сентября 2010

Метод, который разместил Марк Байерс, будет запущен после закрытия основного виджета, что означает, что его элементы управления больше не будут доступны.

Если вам нужно работать с какими-либо значениями из элементов управления в вашей форме, вам нужно будет захватить событие закрытия и выполнить свою работу там:

class MainWidget(QtGui.QWidget):

    #...

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

Также см. Пример окна сообщенияв учебнике по ZetCode Первые программы в наборе инструментов PyQt4 (ближе к концу страницы).Здесь показано, как принять или отменить запрос на закрытие.

4 голосов
/ 30 сентября 2010

Чтобы гарантировать, что функция Python вызывается при завершении процесса, в целом (с участием или без участия Qt ;-), вы можете использовать модуль atexit стандартной библиотеки Python:

import atexit

def whatever(): ...

atexit.register(whatever)

Из соображений благоразумия я бы порекомендовал не использовать связанный метод вместо функции для этой цели - он "должен" работать, но фаза разрушения процесса всегда несколько деликатна, и чем проще вы ее сохраните, тем лучше.

atexit, конечно, не сработает при достаточно сложном сбое процесса (например, если процесс завершается с kill -9, тогда по определению это не дает шанса запустить любой код завершения) - операционная система следит за этим ;-). Если вам нужно справиться с каким-либо сбоем, независимо от того, насколько сложно это сделать из отдельного «сторожевого» процесса, это существенно более сложная проблема.

3 голосов
/ 30 сентября 2010

Введите код от app.exec_ до sys.exit:

ret = app.exec_()
# Your code that must run when the application closes goes here
sys.exit(ret)
1 голос
/ 30 сентября 2010

Найден этот ответ , который включает в себя перегрузку closeEvent ().

он отлично сработал для меня.

...