Search code examples
pythonevent-handlingwxpythonmessagedialog

Continuous event firing wxPython


I have a large GUI application in wxPython. Whenever I hit a button, a MessageDialog shows some results. When clicking OK and X in the dialog the dialog disappears, but the event of the original button is fired again. Thus, the dialog is shown a second time and so it continues infinitely.

My code (minimized to the relevant parts):

import wx
from wx import MessageDialog

class Compiler():

    @staticmethod
    def compile(code):
        dialog = MessageDialog(None, code+'\n\n', caption='Compiler result', style=wx.ICON_ERROR|wx.CENTRE)
        dialog.ShowModal()

class GUI ( wx.Frame ):

    def __init__( self):
        wx.Frame.__init__ ( self, None, id = wx.ID_ANY, title = "Test frame", pos = wx.DefaultPosition, size = wx.Size(200, 300), style = wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.TAB_TRAVERSAL )

        theSizer = wx.GridBagSizer( 0, 0 )

        self.theButton = wx.Button( self, wx.ID_ANY, "Hit me!", wx.DefaultPosition, wx.DefaultSize, 0 )
        theSizer.Add( self.theButton, wx.GBPosition( 0, 0 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )       

        self.SetSizer( theSizer )
        self.Layout()

        self.Centre( wx.BOTH )

        self.theButton.Bind( wx.EVT_LEFT_DOWN, self.execute )

    def execute( self, event ):
        event.Skip()
        print 'Button executed!'
        Compiler.compile('any_input');

if __name__ == '__main__':
    app = wx.App(False)
    GUI().Show() # Launch GUI
    app.MainLoop()

After the button is hit once, clicking anywhere in the frame will cause the event to fire again, why is this happening?


Solution

  • The real bug in your code:

    def execute( self, event ):
        event.Skip()
        print 'Button executed!'
        Compiler.compile('any_input');
    

    is event.Skip(). What it does is keeps propagating the event. The event thus keeps on propagating in the absence of any other event handler and is handled and propagated by this event handler continuously in a loop. Remove the line and it works fine!

    Take a look at this documentation for some more info