pythonwxpythonauto-close

wxMessageBox with an auto-close timer in wxPython


Platforms: Windows, OS X

Python Version: Active State Python 2.7

wxPython Version: Version 2.9

Here is a sample code in which I use a wxMessageBox:

import wx,os

class Frame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(100, 100),style=wx.MINIMIZE_BOX | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN)

        host=os.system('hostname')
        if host!='superman':            
            self.dialogBox=wx.MessageBox('The host name should be superman. Closing this dialog box in 2s...','Info')            
            self.Destroy()
        else:
            self.Center()
            self.Show()

if __name__ == '__main__':
    app = wx.App(redirect=False)
    frame = Frame(None, -1, 'Sample')
    app.MainLoop()

According to the above piece of code, If the host name is not 'superman' , then the user is displayed a message box and prompted to press 'OK'. If the user presses 'OK' button on the message box, then the control moves to the next line in the code (i.e., line number 10) where the frame is destroyed. I want to be to able to automatically close the dialog box and go to the next line in the code i.e., self.Destroy() if the user does not press the 'OK' button in the next 2 seconds. Any thoughts on how do I do that in wxpython ?


Solution

  • I think you might have to use a custom wx.Dialog for this. You can use wx.FutureCall to call trigger an event in the future. Something like:

    class MessageDialog(wx.Dialog):
        def __init__(self, message, title):
            wx.Dialog.__init__(self, None, -1, title,size=(300, 120))
            self.CenterOnScreen(wx.BOTH)
    
            ok = wx.Button(self, wx.ID_OK, "OK")
            ok.SetDefault()
            text = wx.StaticText(self, -1, message)
    
            vbox = wx.BoxSizer(wx.VERTICAL)
            vbox.Add(text, 1, wx.ALIGN_CENTER|wx.TOP, 10)
            vbox.Add(ok, 1, wx.ALIGN_CENTER|wx.BOTTOM, 10)
            self.SetSizer(vbox)
    
    class Frame(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title, size=(100, 100),style=wx.MINIMIZE_BOX | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN)
    
            host=os.system('hostname')
            if host!='superman':
                dlg = MessageDialog('The host name should be superman. Closing this dialog box in 2s...', 'Info')        
                wx.FutureCall(2000, dlg.Destroy)
                dlg.ShowModal()
            else:
                self.Center()
                self.Show()