[PyKDE] Exceptions and event loop (was: Web article on wxWindows and PyQt)
Sundance
sundance at ierne.eu.org
Mon Oct 6 02:58:01 BST 2003
I heard Hans-Peter Jansen said:
> You could redirect stdout/stderr to an internal tee, which would
> trigger a PYSIGNAL, which in turn triggers a corresponding dialog.
I would *really* not want to go that way, if at all possible... I mean,
having to parse a traceback for information, when an exception's
traceback object already contains everything, would be a kludge
unworthy of Python, frankly. :)
> Again, how a about throwing things together to provide a minimum
> example. I will try to help you as I can with the hairy parts ;)
> [I'm somewhat time restricted atm]
Here it goes.
---[ ExceptionHandler.py ]---------------------------------------------
from qt import *
import sys
import os.path
NAME = "MySoftware"
def bug(exception, traceback):
line = traceback.tb_lineno
filename = os.path.basename(traceback.tb_frame.f_code.co_filename)
exception = str(exception)
QMessageBox.critical(None, "Houston, we have a problem...",
"Whoops. A critical error has occured. This is "
+ "most likely a bug in " + NAME + ". The error is:"
+ "<center><b><i>%s</i></b></center>" % exception
+ "It occured at <b>line %d</b> " % line
+ "of file <b>%s</b>." % filename
+ "<br><br>" + NAME + " will now close.<br>")
mainwidget = qApp.mainWidget()
if mainwidget:
mainwidget.close()
else:
qApp.quit()
class MyWidget(QTextEdit):
def keyPressEvent(self, *args):
raise Exception, "Hiya! I'm a bug inside the event loop!"
app = QApplication(sys.argv)
try:
somewidget = MyWidget()
app.setMainWidget(somewidget)
somewidget.show()
raise Exception, "Hiya, I'm a bug outside the event loop!"
app.exec_loop()
except Exception, err:
dummy, exception, traceback = sys.exc_info()
bug(exception, traceback)
-----------------------------------------------------------------------
There. This demonstrates what I'm trying to do.
When you run this code, it 'bugs correctly', so to speak -- the first
exception gets caught, and the exception handler handles it, displays a
nice friendly message, and when you click OK the app quits. I am very
proud of this most professional-looking bug.
Now, comment the raise clause that sits outside the event loop, run the
program again, and when the QTextEdit appears, try to type something
inside it. Since we override the KeyPress event handler with something
that raises an exception, well, that exception will be raised,
obviously: the traceback is displayed in the terminal, and... nothing
else. The event loop just swallows the exception, and our exception
handler is never notified that an exception occured.
This is my problem, and it's fairly annoying. I'm pretty sure there
exists a way to tell the PyQt event loop not to brush the exceptions
under the carpet, since when an exception occurs you generally don't
want to go on running like nothing happened, as the application state
is now likely inconsistent, which might lead to data loss. Only, I have
no idea how to tell that to the event loop.
> Switch comments in close/closeEvent methods to expose qApp.quit()
> and watch the different shut down paths.
Oh. Right. Thanks. =D
-- S.
More information about the PyQt
mailing list