Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 633
user699540 Avatar asked Dec 22 '22 14:12

user699540


1 Answers

If you create your own custom dialog by subclassing wx.Dialog you can use a wx.Timer to generate a periodic event to which you can bind a handler which updates the message every time the timer event fires, then after x event fires you can destroy the dialog.

Working example:

import wx
import os

class MessageDialog(wx.Dialog):
    def __init__(self, message, title, ttl=10):
        wx.Dialog.__init__(self, None, -1, title,size=(400, 150))
        self.CenterOnScreen(wx.BOTH)
        self.timeToLive = ttl

        stdBtnSizer = self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL) 
        stMsg = wx.StaticText(self, -1, message)
        self.stTTLmsg = wx.StaticText(self, -1, 'Closing this dialog box in %ds...'%self.timeToLive)

        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(stMsg, 1, wx.ALIGN_CENTER|wx.TOP, 10)
        vbox.Add(self.stTTLmsg,1, wx.ALIGN_CENTER|wx.TOP, 10)
        vbox.Add(stdBtnSizer,1, wx.ALIGN_CENTER|wx.TOP, 10)
        self.SetSizer(vbox)

        self.timer = wx.Timer(self)
        self.timer.Start(1000)#Generate a timer event every second
        self.timeToLive = 10 
        self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)

    def onTimer(self, evt):
        self.timeToLive -= 1
        self.stTTLmsg.SetLabel('Closing this dialog box in %ds...'%self.timeToLive)

        if self.timeToLive == 0:
            self.timer.Stop()
            self.Destroy()

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', 'Info', ttl=10)               
            dlg.ShowModal()
        else:
            self.Center()
            self.Show()

if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = Frame(None, -1, "") 
    frame.Show(1)
    app.MainLoop()
like image 101
volting Avatar answered Jan 09 '23 08:01

volting