Search code examples
modal-dialogwxpython

Shake wx.Dialog after validation fails


I have a wx.Dialog with a custom validation process that runs after the OK button is pressed. If the validation fails I would like to shake the wx.Dialog to let users know that something is wrong with the given input.

Is there something like this implemented in wxPython?


Solution

  • The simplest way, would be activate a wx.Timer with a short interval that moves the dialog's position, when the processing fails.

    Something like this:

    import wx
    
    class Busy(wx.Dialog):
        def __init__(self, parent):
            wx.Dialog.__init__(self, parent, wx.ID_ANY, "Busy", size= (420,240))
            self.panel = wx.Panel(self,wx.ID_ANY)
            self.label = wx.StaticText(self.panel, label="Processing..................", pos=(120,20))
            self.gauge = wx.Gauge(self.panel,size=(300,25),pos=(80,80))
            self.livelabel = wx.StaticText(self.panel, label="Time to live:", pos=(80,110))
            self.lltime = wx.StaticText(self.panel, label="10", pos=(160,110))
            self.closeButton =wx.Button(self.panel, label="Cancel", pos=(180,160))
            self.closeButton.Bind(wx.EVT_BUTTON, self.OnQuit)
            self.Bind(wx.EVT_CLOSE, self.OnQuit)
            self.timer = wx.Timer(self)
            self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
            self.lifetimer = wx.Timer(self)
            self.Bind(wx.EVT_TIMER, self.OnLifeTimer, self.lifetimer)
            self.lifetimer.Start(1000)
            self.life = 10
            self.Show()
            self.alt_pos = False
    
        def OnTimer(self, event):
            curr_pos_x, curr_pos_y = self.GetPosition()
            if self.alt_pos:
                self.Move(curr_pos_x+2, curr_pos_y)
                self.alt_pos = False
            else:            
                self.Move(curr_pos_x+-2, curr_pos_y)            
                self.alt_pos = True
    
        def OnLifeTimer(self, evt): #Update time to live
            self.gauge.Pulse()
            self.life -= 1
            self.lltime.SetLabelText(str(self.life))
            if self.timer.IsRunning() or self.life > 0:
                return
            else:
                self.label.SetLabel("Timed Out")
                self.timer.Start(50)
    
        def OnQuit(self, event):
            self.timer.Stop()
            self.lifetimer.Stop()
            self.result_text = None
            self.EndModal(False)
    
    app = wx.App()
    dlg = Busy(parent = None)
    result = dlg.ShowModal()
    print (result)
    if result:
        print (dlg.result_text)
    else:
        print ("Dialog Cancelled")
    dlg.Destroy()
    

    enter image description here