Befehl vor Programmende noch ausführen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Caldar
User
Beiträge: 46
Registriert: Sonntag 17. Mai 2009, 18:20

Ist es möglich, beim Terminieren einer PyQt-GUI-Applikation (mittels X in der Titelleiste) zuvor noch einen Befehl auszuführen?
Konkret geht es bei mir darum, ein Connection-Objekt (MySQldb) per close() zu schließen, bevor die GUI-Applikation beendet wird.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Neugierde
User
Beiträge: 2
Registriert: Samstag 23. Mai 2009, 15:25

Hallo,

bei QWidget und damit bei auch bei QMainWindow gibt es closeEvent ( QCloseEvent * event ).

Wenn das Hauptfenster von QMainWindow erbt, kann man closeEvent reimplementieren und sie wird beim "X" drücken aufgerufen.

Viele Grüße
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich sehe in beiden Verfahren das Problem, dass am Ende ein Fehlerwert von 0 zurückgegeben wird. Das hätte ich zumindest bei `atexit` nicht erwartet (hab's aber auch noch nie benutzt). Hier mal ein sinnfreies Beispiel bei der Verwendung von `atexit`:

test.py:

Code: Alles auswählen

import atexit
import sys

from PyQt4 import QtGui


class MainWindow(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)


def cleanup(number):
    int(number)

atexit.register(cleanup, 'not a number')


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    exitcode = app.exec_()
    print 'GUI exited with', exitcode
Ausgabe:

Code: Alles auswählen

sebastian@deepthought:~/bin$ python test.py
GUI exited with 0
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "test.py", line 14, in cleanup
    int(number)
ValueError: invalid literal for int() with base 10: 'not a number'
Error in sys.exitfunc:
Traceback (most recent call last):
  File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "test.py", line 14, in cleanup
    int(number)
ValueError: invalid literal for int() with base 10: 'not a number'
sebastian@deepthought:~/bin$ echo $?
0
Dass die GUI mit 0 endet, ist eigentlich klar. Ich sehe ich es auch als problematisch an, grundsätzlich auf `closeEvent()` zu verweisen, da dort geworfene Exceptions die GUI trotzdem mit 0 enden lassen. Und wenn kein Dialogfeld, sondern eine interne Aufräum-Aktion, wie im Beispiel, geplant ist, dann hat das ja sowieso nichts mehr mit der GUI zu tun und sollte IMHO von "außen" geregelt werden. Ich hatte nur eigentlich erwartet, dass mir eine Exception in Zusammenhang mit `atexit` eben *kein* 0 zurückgibt und Python den Fehlercode - wie sonst auch bei Exceptions - für einen automatisch auf 1 setzt.

Mein Lösungsvorschlag: Sofern die grafische Oberfläche am Ende nicht mehr benötigt wird, könntest du die GUI ja ganz normal im Quelltext starten und danach das schreiben, was noch ausgeführt werden soll. Sobald der Anwender das Fenster schließt, wird dann halt der "Finalize-Kram" (was auch immer) gemacht. Denn es wird in dem Moment ja nur Qt's Mainloop verlassen. Das Python-Programm läuft noch weiter.

Oder noch besser:

Code: Alles auswählen

try:
    app.exec_()
finally:
    cleanup()
Antworten