Problme with destroying wx.MessageDialog

Hi,
Observed something even strange …
I used key to select a button and at the first instance the label got
highlighted. Then the NO button … then I clicked on it … then it gives me the
intended behaviour…
Very strange …
Anyone know why this happens ?

···

On Sun, Mar 15, 2009 at 10:45 PM, Kenneth Thilakarathna attalaya@gmail.com wrote:

Hi,
I am having a problem where the MessageDialog wont get destroyed until
the application comes to an end…

Please help …
I created a function so that I could change the question string and reuse it.

code

import sys,wx,time

def yesno(str_msg):
app = wx.PySimpleApp(redirect=False)
dlg = wx.MessageDialog(None, str_msg, “Question”, wx.YES_NO| wx.ICON_QUESTION)
result=dlg.ShowModal()==wx.ID_YES

dlg.Destroy()
return result

while True:
strmsg=“My question”
result=yesno(strmsg)
print result
time.sleep(3)

==================
Please help


Get the benefit
Patch a snippet
Leave the credit

සුභ දවසක්
Have a nice Day
කෙනෙත් තිලකරත්න
Kenneth Thilakarathna


Get the benefit
Patch a snippet
Leave the credit

සුභ දවසක්
Have a nice Day
කෙනෙත් තිලකරත්න
Kenneth Thilakarathna

Kenneth, I think you didn't quite get the wxPython way of doing things.
The app is screaming "START ME!!!". You must call app.MainLoop()
before handling windows and dialogs that way.

The way you are creating and handling widgets is quite strange, that's
why it behaves so erratically. A common (and very simple) wxPython
window goes along this lines:

import wx
app = wx.PySimpleApp()
frame = wx.Frame(None, wx.ID_ANY, "Hello World")
frame.Show(True)
app.MainLoop()

If you explain better what you are trying to do (for example why do
you need infinite dialogs without a main frame), we could try to do it
in a more common way.

One more thing I forgot to add:
The http://zetcode.com/wxpython/dialogs/ site has an excellent quick
guide to message dialogs.

I tried to achieve the same effect that you (seemed to) want using an
invisible frame behind the dialogs.

import wx

def CreateMessageDialog(text):
  dlg = wx.MessageDialog(None, text, "Question", wx.YES_NO| wx.ICON_QUESTION)
  value = dlg.ShowModal()==wx.ID_YES
  dlg.Destroy()
  return value

class MyFrame(wx.Frame):
  def __init__ (self, *args, **kargs):
    wx.Frame.__init__(self, *args, **kargs)
    
    while True:
      value = CreateMessageDialog("My Question")
      if not value:
        break
      
    self.Destroy()

app = wx.App()
MyFrame(None, -1)
app.MainLoop()

For limited patience reasons it will stop spawing new dialogs if the
user answers "No". If the code doesn't indent well in this email,
please check the attachment.

And I just realized that I repeated the word "way" too much on my last message.

GUITest.py (449 Bytes)

Third message in a row :facepalm:

Sorry, I was horribly wrong somewhere. In my last code the
app.MainLoop() was not even called before the dialogs windows started
spawning.

And about your problems, I now blame the time.sleep function. It seems
to completely freeze the application while, under the hood, wxPython
was trying to destroy the dialog.

Thank you for replying me Lucas …
You are very right … I tried it in that way also … but no success …

My purpose of doing this is to create an ad hoc network connection
For that once I start a machine with wi-fi card the program should

ask user whether to connect to an existing network or create a new
one …
If he disagree program have to scan for available adhoc connections time to
time. When the program finds an ad hoc network, program will prompt for

connection. If it also being canceled by the user again the program will listen
to any new ad hoc networks…

For the program to be wait for some time I have called wx.Sleep() or time.sleep()

After incorporating this sleep method I got into this problem …

I am only a week old boy in Python arena … so still trying to grasp things. …

Even the program you sent I just tried to make the program sleep for 2 sec …
Got the same problem…

···

On Tue, Mar 17, 2009 at 12:09 AM, Lucas Boppre Niehues lucasboppre@gmail.com wrote:

Kenneth, I think you didn’t quite get the wxPython way of doing things.

The app is screaming “START ME!!!”. You must call app.MainLoop()

before handling windows and dialogs that way.

The way you are creating and handling widgets is quite strange, that’s

why it behaves so erratically. A common (and very simple) wxPython

window goes along this lines:

import wx

app = wx.PySimpleApp()

frame = wx.Frame(None, wx.ID_ANY, “Hello World”)

frame.Show(True)

app.MainLoop()

If you explain better what you are trying to do (for example why do

you need infinite dialogs without a main frame), we could try to do it

in a more common way.


wxpython-users mailing list
wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users


Get the benefit
Patch a snippet
Leave the credit

සුභ දවසක්
Have a nice Day
කෙනෙත් තිලකරත්න
Kenneth Thilakarathna

Kenneth Thilakarathna wrote:

Thank you for replying me Lucas ...
You are very right ... I tried it in that way also ... but no success ..

My purpose of doing this is to create an ad hoc network connection
For that once I start a machine with wi-fi card the program should
ask user whether to connect to an existing network or create a new
one ...
If he disagree program have to scan for available adhoc connections time to
time. When the program finds an ad hoc network, program will prompt for
connection. If it also being canceled by the user again the program will listen
to any new ad hoc networks...

For the program to be wait for some time I have called wx.Sleep() or time.sleep()

After incorporating this sleep method I got into this problem ....

I am only a week old boy in Python arena ... so still trying to grasp things. ..

Even the program you sent I just tried to make the program sleep for 2 sec ..
Got the same problem...

Anytime you block the immediate return the MainLoop then you are preventing events from being delivered, and the GUI will appear to freeze. See:

http://wiki.wxpython.org/LongRunningTasks
http://wiki.wxpython.org/Non-Blocking_Gui

···

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

Building on Lucas’ solution, I offer mine, using wx.Timer :

import wx

def CreateMessageDialog(text):
dlg = wx.MessageDialog(None, text, “Question”, wx.YES_NO | wx.ICON_QUESTION)
value = dlg.ShowModal()==wx.ID_YES

return value

class App(wx.App):
def OnInit(self):
self.ExitOnFrameDelete = False
frame=wx.Frame(None, title=“Useless frame”)
wx.CallAfter(frame.Destroy)
self.timer = wx.Timer(self)

    self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
    self.timer.Start(milliseconds=3000, oneShot=True)
    return True

def OnTimer(self, evt):
    value = CreateMessageDialog("My Question")

    if value:
        self.timer.Start(oneShot=True)
    else:
        self.ExitMainLoop()

app = App()
app.MainLoop()

This makes dialogs reappear every 3 seconds as long as you click “Yes”.

A few comments:

  • As Robin hinted, one should probably never call wx.Sleep() from the main GUI thread, so I think that using wx.Timer is the canonical way of solving your problem.
  • Creating the “useless frame” seems a dirty hack. Yet if I don’t create it, the application exits immediately. On the other hand, if I show it, it’s irrelevant to the application’s behaviour.
  • There seems to be a small bug with app.ExitOnFrameDelete, it defaults to False even though everything seems to behave as if it were True. Setting it once suppresses the inconsistency. (Tested on WinXP, wx 2.8.9.1, python 2.5)

Hi,
I have gone through the docs Robin sent and they seems really helpful …
It is a shame that I couldn’t find those even after I have searched for the problem
for two days. Yesterday I found the book wxPython in action book and will get one. Hope it will help
me for rest of the stuff and if not, now I know the right place to come.
Occupied with some paper writing and will try them and let you know
Thank you and I really appreciate your advice Robin .

and yes Ronan your code works in GNU/Linux Ubuntu Intrepid Python 2.5.2
and wxPython 2.8.9.2 …
Thank you very much for your code snippet and seems it could also be used.

Thank you Lucas for for your effort to get me a solution …

This is why I love Open source community, you are never alone …

···

2009/3/17 Ronan Lamy Ronan.Lamy@normalesup.org

Building on Lucas’ solution, I offer mine, using wx.Timer :

import wx

def CreateMessageDialog(text):

dlg = wx.MessageDialog(None, text, “Question”, wx.YES_NO | wx.ICON_QUESTION)

value = dlg.ShowModal()==wx.ID_YES


return value

class App(wx.App):
def OnInit(self):
self.ExitOnFrameDelete = False
frame=wx.Frame(None, title=“Useless frame”)
wx.CallAfter(frame.Destroy)
self.timer = wx.Timer(self)

    self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
    self.timer.Start(milliseconds=3000, oneShot=True)
    return True

def OnTimer(self, evt):
    value = CreateMessageDialog("My Question")



    if value:
        self.timer.Start(oneShot=True)
    else:
        self.ExitMainLoop()

app = App()
app.MainLoop()

This makes dialogs reappear every 3 seconds as long as you click “Yes”.

A few comments:

  • As Robin hinted, one should probably never call wx.Sleep() from the main GUI thread, so I think that using wx.Timer is the canonical way of solving your problem.

  • Creating the “useless frame” seems a dirty hack. Yet if I don’t create it, the application exits immediately. On the other hand, if I show it, it’s irrelevant to the application’s behaviour.

  • There seems to be a small bug with app.ExitOnFrameDelete, it defaults to False even though everything seems to behave as if it were True. Setting it once suppresses the inconsistency. (Tested on WinXP, wx 2.8.9.1, python 2.5)


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users


Get the benefit
Patch a snippet
Leave the credit

සුභ දවසක්
Have a nice Day
කෙනෙත් තිලකරත්න
Kenneth Thilakarathna

Kenneth Thilakarathna wrote:

Hi,
I have gone through the docs Robin sent and they seems really helpful ..
It is a shame that I couldn't find those even after I have searched for the problem
for two days. Yesterday I found the book wxPython in action book and will get one. Hope it will help
me for rest of the stuff and if not, now I know the right place to come.
Occupied with some paper writing and will try them and let you know
Thank you and I really appreciate your advice Robin .

and yes Ronan your code works in GNU/Linux Ubuntu Intrepid Python 2.5.2
and wxPython 2.8.9.2 ...
Thank you very much for your code snippet and seems it could also be used.

Thank you Lucas for for your effort to get me a solution ...

This is why I love Open source community, you are never alone ...

Robin's book is definitely a good way to learn the basics and some of the nitty gritty of the wxPython package. There have been some widgets added since the book was written and a few changes as well. Just ask here for help and you'll probably get it within a few hours.

- Mike

···

2009/3/17 Ronan Lamy <Ronan.Lamy@normalesup.org <mailto:Ronan.Lamy@normalesup.org>>

    Building on Lucas' solution, I offer mine, using wx.Timer :

    import wx

    def CreateMessageDialog(text):
        dlg = wx.MessageDialog(None, text, "Question", wx.YES_NO |
    wx.ICON_QUESTION)
        value = dlg.ShowModal()==wx.ID_YES
        return value

    class App(wx.App):
        def OnInit(self):
            self.ExitOnFrameDelete = False
            frame=wx.Frame(None, title="Useless frame")
            wx.CallAfter(frame.Destroy)
            self.timer = wx.Timer(self)
            self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
            self.timer.Start(milliseconds=3000, oneShot=True)
            return True

        def OnTimer(self, evt):
            value = CreateMessageDialog("My Question")
            if value:
                self.timer.Start(oneShot=True)
            else:
                self.ExitMainLoop()

    app = App()
    app.MainLoop()

    This makes dialogs reappear every 3 seconds as long as you click
    "Yes".

    A few comments:
    * As Robin hinted, one should probably never call wx.Sleep() from
    the main GUI thread, so I think that using wx.Timer is the
    canonical way of solving your problem.
    * Creating the "useless frame" seems a dirty hack. Yet if I don't
    create it, the application exits immediately. On the other hand,
    if I show it, it's irrelevant to the application's behaviour.
    * There seems to be a small bug with app.ExitOnFrameDelete, it
    defaults to False even though everything seems to behave as if it
    were True. Setting it once suppresses the inconsistency. (Tested
    on WinXP, wx 2.8.9.1, python 2.5)

    _______________________________________________
    wxpython-users mailing list
    wxpython-users@lists.wxwidgets.org
    <mailto:wxpython-users@lists.wxwidgets.org>
    http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

--
********************
Get the benefit Patch a snippet Leave the credit

සුභ දවසක්
Have a nice Day
කෙනෙත් තිලකරත්න
Kenneth Thilakarathna

------------------------------------------------------------------------

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users