Have a look at sys.excepthookI 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. _______________________________________________ PyKDE mailing list [EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
The attached code shows an example:
Ulli
#============================================================================# # Catching exception in qt applications # #----------------------------------------------------------------------------# import sys, string, traceback from qt import * #============================================================================# # Exception handler that shows the traceback in a message box end exists the # # application. # #----------------------------------------------------------------------------# def my_excepthook(exc_type, exc_value, exc_traceback): msg = string.joinfields(traceback.format_exception(exc_type, exc_value, exc_traceback)) QMessageBox.critical(None, app.tr("Critical Error"), app.tr("An unexpected Excption has occured!\n" "The Application will exit now.\n\n%1").arg(msg), QMessageBox.Ok, QMessageBox.NoButton, QMessageBox.NoButton) # Call the default exception handler if you want sys.__excepthook__(exc_type, exc_value, exc_traceback) app.quit() #============================================================================# # Install the new exception handler, the default handler is always available # # as sys.__excepthook__ # #----------------------------------------------------------------------------# sys.excepthook = my_excepthook #============================================================================# # Main startup # #----------------------------------------------------------------------------# if __name__ == '__main__': app = QApplication(sys.argv) ... ... ... app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")); app.exec_loop() #============================================================================# # EOF # #----------------------------------------------------------------------------#