MessageDialog.EndModal() fails?

I am trying to create a subclass of wx.MessageDialog that displays a message and that times out and goes away after a given period. I use a wx.Timer to call a method when the timer times out. This method calls the EndModal on self. However I get an assertion error: EndModal called for a non-modal dialog, even though I have called ShowModal on my instance. I must be missing something! The class and a demo is below.
Thanks,
Hank

import wx

class TimedMessageDialog(wx.MessageDialog):
    """
    This specialised sublcass of wex.MessageDialog takes a timeout parameter; it
    behaves like a wx.MessageDialog, but it will go away automatically when the
    timeout period expires. A value of 0 means the message never times out.
    """
    def __init__(self,parentWin,message,
                 timeout=0,
                 caption="Message box",
                 style=wx.OK|wx.CANCEL,
                 pos=wx.DefaultPosition):
        self._timeout=timeout
        wx.MessageDialog.__init__(self,parentWin,message,caption=caption,style=style,pos=pos)

    def ShowModal(self):
        self._startTimer()
        self.MakeModal(True)
        wx.MessageDialog.ShowModal(self)
           def _startTimer(self):
        if self._timeout>0:
            self._timer=wx.Timer(self)
            self._timer.Start(self._timeout*1000,wx.TIMER_ONE_SHOT)
            self.Bind(wx.EVT_TIMER,self._onTimeout,self._timer)
               def _onTimeout(self,evt):
        wx.Dialog.EndModal(self,wx.OK)

class Test(wx.App):
    def OnInit(self):
        self.frame=wx.Frame(None,-1)
        panel=wx.Panel(self.frame,-1)
        self.panel=panel
        self.frame.Show()
        wx.CallAfter(self.testTMD)
        return(True)

    def testTMD(self):
        tmd=TimedMessageDialog(self.panel,'Minkey',4)
        tmd.ShowModal()
        tmd.Destroy()
        self.frame.Destroy()

app=Test(redirect=False)
app.MainLoop()

Hank Knox wrote:

I am trying to create a subclass of wx.MessageDialog that displays a message and that times out and goes away after a given period. I use a wx.Timer to call a method when the timer times out. This method calls the EndModal on self. However I get an assertion error: EndModal called for a non-modal dialog, even though I have called ShowModal on my instance. I must be missing something! The class and a demo is below.

wx.MessageDialog is not a real wx.Dialog. Its ShowModal is just a wrapper around a system API function that creates and shows the dialog internally.

To do what you are trying you will need to derive a new message class from wx.Dialog. There is some code in the demo that you can use as a starting point for simulating the layout, icon and etc. of the message dialog. Look at MessagePanel in Main.py.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Thanks. I'll do that.
Hank

Robin Dunn wrote:

···

Hank Knox wrote:

I am trying to create a subclass of wx.MessageDialog that displays a message and that times out and goes away after a given period. I use a wx.Timer to call a method when the timer times out. This method calls the EndModal on self. However I get an assertion error: EndModal called for a non-modal dialog, even though I have called ShowModal on my instance. I must be missing something! The class and a demo is below.

wx.MessageDialog is not a real wx.Dialog. Its ShowModal is just a wrapper around a system API function that creates and shows the dialog internally.

To do what you are trying you will need to derive a new message class from wx.Dialog. There is some code in the demo that you can use as a starting point for simulating the layout, icon and etc. of the message dialog. Look at MessagePanel in Main.py.