[PyKDE] problem with exceptions within events

Ulrich Berning ulrich.berning at desys.de
Thu Feb 24 14:53:45 GMT 2005


Toby Dickenson schrieb:

>On Thursday 24 February 2005 00:44, Giovanni Bajo wrote:
>
>  
>
>>I reckon you have slightly misunderstood my problem.
>>    
>>
>
>I had misunderstood it too. 
>
>  
>
>>The problem is: when the exception is raised from within the overriden
>>method of an event handler (as opposed to an exception raised from within
>>the constructor of a subclass, or from within a slot called by a signal),
>>the exception is *totally* ignored. There is no acknowledgement
>>whatsoever. Nothing. Nada. I have no way to know that my code did not
>>work.
>>    
>>
>
>Ive attached a test script based on your original report. I cant reproduce the 
>problem here with sip 4.0.1, PyQt 3.1.2, qt 3.3.3
>
>  
>
>>I would expect the
>>exception raised by the event handler to call our custom excepthook just
>>like other exceptions raised in different contexts, but it would be fine
>>if it *just* printed something on the console. 
>>    
>>
>
>Agreed.
>
>  
>
I have attached a more practical example, that shows the problem in more 
detail. If you use sendEvent(), everything is fine (at least for me) and 
the exepthook function is called. This is because the event is 
immediately processed. With postEvent(), the event processing is 
deferred until control returns to the main loop and the excepthook 
function is not called. I think, this has to do with the fact, that the 
ownership of the event is taken by the post event queue and the event is 
deleted once it has been posted.

In your example you first called sendEvent(), then postEvent() and then 
processEvents(). By calling postEvent() followed by processEvents(), you 
simulate the behavior of sendEvent(). Uncomment the processEvents() call 
in my script and you will get the same result as with sendEvent().

Ulli

-------------- next part --------------
#!/usr/bin/env python
#============================================================================#
# Imports                                                                    #
#----------------------------------------------------------------------------#
import sys, string, traceback, qt

#============================================================================#
# Excepthook catching unhandled exceptions                                   #
#----------------------------------------------------------------------------#
def my_excepthook(exc_type, exc_value, exc_traceback):
    sys.stderr.write("in my_excepthook()\n")
    trb = string.join(traceback.format_exception(exc_type,
                                                 exc_value,
                                                 exc_traceback))
    id =qt.QMessageBox.critical(None,
                                "Unhandled Exception caught",
                                trb,
                                qt.QMessageBox.Ignore,
                                qt.QMessageBox.Abort)
    if id == qt.QMessageBox.Abort:
        sys.stderr.write("Aborting application...\n")
        qt.qApp.exit()
    else:
        sys.stderr.write("Continuing application... (may give you unexpected behavior)\n")
    
#============================================================================#
# Main widget                                                                #
#----------------------------------------------------------------------------#
class MainWidget(qt.QWidget):
    def __init__(self, parent=None, name=None, fl=0):
        qt.QWidget.__init__(self, parent, name, fl)

        # Create custom event type
        self.myEventType = qt.QEvent.Type(qt.QEvent.User)

        # Create the widget layout
        self.vbox = qt.QVBoxLayout(self, 11, 6)

        # A radio button group to select the event method
        self.groupMethod = qt.QButtonGroup(1, qt.QGroupBox.Horizontal, "Event Delivery Method", self)
        self.groupMethod.setExclusive(True)
        self.vbox.addWidget(self.groupMethod)
        self.methodSend = qt.QRadioButton("&sendEvent()", self.groupMethod)
        self.methodSend.setChecked(True)
        self.methodPost = qt.QRadioButton("&postEvent()", self.groupMethod)

        # A buuton group with a push button
        self.groupEvent = qt.QButtonGroup(1, qt.QGroupBox.Horizontal, "Generate Custom Event", self)
        self.vbox.addWidget(self.groupEvent)
        self.button = qt.QPushButton("Raises &ZeroDivisonError", self.groupEvent)
        self.connect(self.button, qt.SIGNAL("clicked()"), self.slotButton)

    # Push button slot
    def slotButton(self):
        if self.methodPost.isChecked():
            qt.qApp.postEvent(self, qt.QCustomEvent(self.myEventType))
#            qt.qApp.processEvents()
        else:
            qt.qApp.sendEvent(self, qt.QCustomEvent(self.myEventType))

    # Custom event handler
    def customEvent(self, e):
        sys.stderr.write("in customEvent()\n")
        if e.type() == self.myEventType:
            x = 1 / 0
            
#============================================================================#
# Main programm                                                              #
#----------------------------------------------------------------------------#
sys.excepthook = my_excepthook
a = qt.QApplication(sys.argv)
main_widget = MainWidget()
main_widget.setCaption("Test")
a.setMainWidget(main_widget)
main_widget.show()
a.exec_loop()

#============================================================================#
# EOF                                                                        #
#----------------------------------------------------------------------------#


More information about the PyQt mailing list