[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Who's to blame?

Nicola Musatti

1/3/2008 2:48:00 PM

Hallo,
First of all I apologize for the longish example at the bottom, but
the biggest source file is automatically generated and I didn't want
to modify more than strictly necessary. Also, it would be shorter if
XML wasn't so verbose ;-)

The following is a wxPython/XRC toy program with a form with a button
which, when pressed, causes a simple dialog to be displayed. The
problem lies in the fact that apparently ShowModal() does not return
when either the Yes or the No buttons are pressed. Curiously, if you
change the Yes and No buttons with the OK and Cancel ones that are
currently commented everything works as expected.

As the sbs_test_xrc.py file below is automatically generated by
wxPython 2.8.6.1's XRCed tool from a XRC file which in turn is
generated by wxFormBuilder (http://wxformbu...), I really cant
figure out to whom I should report this problem, assuming I'm not
missing some obvious mistake of mine, that is.

Thanks for your help.

Cheers,
Nicola Musatti

# sbs_test.py
import wx
import sbs_test_xrc

class MainFrame(sbs_test_xrc.xrcMainFrame):
def __init__(self, parent):
sbs_test_xrc.xrcMainFrame.__init__(self, parent)
self.button.Bind(wx.EVT_BUTTON, self.OnButton)

def OnButton(self, event=None):
d = sbs_test_xrc.xrcDialog(self)
## if d.ShowModal() == wx.ID_OK:
if d.ShowModal() == wx.ID_YES:
self.Close()

class Application(wx.App):
def OnInit(self):
self.frame = MainFrame(None)
self.frame.Show()
self.SetTopWindow(self.frame)
return True

if __name__ == '__main__':
app = Application()
app.MainLoop()

# sbs_test_xrc.py
# This file was automatically generated by pywxrc, do not edit by
hand.
# -*- coding: UTF-8 -*-

import wx
import wx.xrc as xrc

__res = None

def get_resources():
""" This function provides access to the XML resources in this
module."""
global __res
if __res == None:
__init_resources()
return __res

class xrcDialog(wx.Dialog):
def PreCreate(self, pre):
""" This function is called during the class's initialization.

Override it for custom setup before the window is created
usually to
set additional window styles using SetWindowStyle() and
SetExtraStyle()."""
pass

def __init__(self, parent):
# Two stage creation (see http://wiki.wxpython.org/index.cgi/TwoSta...)
pre = wx.PreDialog()
self.PreCreate(pre)
get_resources().LoadOnDialog(pre, parent, "Dialog")
self.PostCreate(pre)

# create attributes for the named items in this container
self.wxID_YES = xrc.XRCCTRL(self, "wxID_YES")
self.wxID_NO = xrc.XRCCTRL(self, "wxID_NO")

class xrcMainFrame(wx.Frame):
def PreCreate(self, pre):
""" This function is called during the class's initialization.

Override it for custom setup before the window is created
usually to
set additional window styles using SetWindowStyle() and
SetExtraStyle()."""
pass

def __init__(self, parent):
# Two stage creation (see http://wiki.wxpython.org/index.cgi/TwoSta...)
pre = wx.PreFrame()
self.PreCreate(pre)
get_resources().LoadOnFrame(pre, parent, "MainFrame")
self.PostCreate(pre)

# create attributes for the named items in this container
self.button = xrc.XRCCTRL(self, "button")

# ------------------------ Resource data ----------------------

def __init_resources():
global __res
__res = xrc.EmptyXmlResource()

wx.FileSystem.AddHandler(wx.MemoryFSHandler())

sbs_test_xrc = '''<?xml version="1.0" ?><resource version="2.3.0.1" xmlns="http://
www.wxwindows.org/wxxrc">
<object class="wxDialog" name="Dialog">
<style>wxDEFAULT_DIALOG_STYLE</style>
<title/>
<object class="wxFlexGridSizer">
<rows>2</rows>
<cols>2</cols>
<vgap>0</vgap>
<hgap>0</hgap>
<growablecols/>
<growablerows/>
<object class="sizeritem">
<option>1</option>
<flag>wxEXPAND</flag>
<border>5</border>
<object class="wxStdDialogButtonSizer">
<object class="button">
<flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
<border>5</border>
<!--
<object class="wxButton" name="wxID_OK">
<label>&amp;OK</label>
</object>
-->
<object class="wxButton" name="wxID_YES">
<label>&amp;Yes</label>
</object>
</object>
<object class="button">
<flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
<border>5</border>
<!--
<object class="wxButton" name="wxID_CANCEL">
<label>&amp;Cancel</label>
</object>
-->
<object class="wxButton" name="wxID_NO">
<label>&amp;No</label>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="wxFrame" name="MainFrame">
<style>wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL</style>
<size>500,300</size>
<title/>
<object class="wxButton" name="button">
<label>MyButton</label>
<default>0</default>
</object>
</object>
</resource>'''

wx.MemoryFSHandler.AddFile('XRC/sbs_test/sbs_test_xrc',
sbs_test_xrc)
__res.Load('memory:XRC/sbs_test/sbs_test_xrc')
5 Answers

Rob Williscroft

1/3/2008 4:48:00 PM

0

Nicola Musatti wrote in news:92dfc2fc-0677-43c0-b34f-4f240fa40205
@e4g2000hsg.googlegroups.com in comp.lang.python:

Note there is a wxpython mailinglist/newsgroup:

news:gmane.comp.python.wxpython

[snip]
> problem lies in the fact that apparently ShowModal() does not return
> when either the Yes or the No buttons are pressed. Curiously, if you
> change the Yes and No buttons with the OK and Cancel ones that are
> currently commented everything works as expected.

This is because the wx.Dialog class has handlers for the wxID_OK
and wxID_CANCEL button identifiers, IIRC in windows the MS supplied
dialog procedure behaves this way.

>
> As the sbs_test_xrc.py file below is automatically generated by
> wxPython 2.8.6.1's XRCed tool from a XRC file which in turn is
> generated by wxFormBuilder (http://wxformbu...), I really cant
> figure out to whom I should report this problem, assuming I'm not
> missing some obvious mistake of mine, that is.

> class MainFrame(sbs_test_xrc.xrcMainFrame):
> def __init__(self, parent):
> sbs_test_xrc.xrcMainFrame.__init__(self, parent)
> self.button.Bind(wx.EVT_BUTTON, self.OnButton)

First you can make the dialog a member, you are showing and hiding it
so there is no need to create a new one every time OnButton is fired.

self.dialog = sbs_test_xrc.xrcDialog(self)

# now replace the defaults of ID_OK and ID_CANCEL
#
self.dialog.SetAffirmativeId( wxID_YES )
self.dialog.SetEscapeId( wxID_NO )

Alternativly you could derive from xrcDialog as you are with
xrcMainFrame and do the above in the derived classes __init__.

> def OnButton(self, event=None):
> d = sbs_test_xrc.xrcDialog(self)
> ## if d.ShowModal() == wx.ID_OK:
> if d.ShowModal() == wx.ID_YES:
> self.Close()
>

http://www.wxpython.org/docs/api/wx.Dialog-...

Rob.
--
http://www.victim-prime.dsl....

Mike Driscoll

1/3/2008 7:19:00 PM

0

On Jan 3, 8:48 am, Nicola Musatti <nicola.musa...@gmail.com> wrote:
> Hallo,
> First of all I apologize for the longish example at the bottom, but
> the biggest source file is automatically generated and I didn't want
> to modify more than strictly necessary. Also, it would be shorter if
> XML wasn't so verbose ;-)
>
> The following is a wxPython/XRC toy program with a form with a button
> which, when pressed, causes a simple dialog to be displayed. The
> problem lies in the fact that apparently ShowModal() does not return
> when either the Yes or the No buttons are pressed. Curiously, if you
> change the Yes and No buttons with the OK and Cancel ones that are
> currently commented everything works as expected.
>
> As the sbs_test_xrc.py file below is automatically generated by
> wxPython 2.8.6.1's XRCed tool from a XRC file which in turn is
> generated by wxFormBuilder (http://wxformbu...), I really cant
> figure out to whom I should report this problem, assuming I'm not
> missing some obvious mistake of mine, that is.
>
> Thanks for your help.
>
> Cheers,
> Nicola Musatti
>
> # sbs_test.py
> import wx
> import sbs_test_xrc
>
> class MainFrame(sbs_test_xrc.xrcMainFrame):
> def __init__(self, parent):
> sbs_test_xrc.xrcMainFrame.__init__(self, parent)
> self.button.Bind(wx.EVT_BUTTON, self.OnButton)
>
> def OnButton(self, event=None):
> d = sbs_test_xrc.xrcDialog(self)
> ## if d.ShowModal() == wx.ID_OK:
> if d.ShowModal() == wx.ID_YES:
> self.Close()
>
> class Application(wx.App):
> def OnInit(self):
> self.frame = MainFrame(None)
> self.frame.Show()
> self.SetTopWindow(self.frame)
> return True
>
> if __name__ == '__main__':
> app = Application()
> app.MainLoop()
>
> # sbs_test_xrc.py
> # This file was automatically generated by pywxrc, do not edit by
> hand.
> # -*- coding: UTF-8 -*-
>
> import wx
> import wx.xrc as xrc
>
> __res = None
>
> def get_resources():
> """ This function provides access to the XML resources in this
> module."""
> global __res
> if __res == None:
> __init_resources()
> return __res
>
> class xrcDialog(wx.Dialog):
> def PreCreate(self, pre):
> """ This function is called during the class's initialization.
>
> Override it for custom setup before the window is created
> usually to
> set additional window styles using SetWindowStyle() and
> SetExtraStyle()."""
> pass
>
> def __init__(self, parent):
> # Two stage creation (seehttp://wiki.wxpython.org/index.cgi/TwoSta...)
> pre = wx.PreDialog()
> self.PreCreate(pre)
> get_resources().LoadOnDialog(pre, parent, "Dialog")
> self.PostCreate(pre)
>
> # create attributes for the named items in this container
> self.wxID_YES = xrc.XRCCTRL(self, "wxID_YES")
> self.wxID_NO = xrc.XRCCTRL(self, "wxID_NO")
>
> class xrcMainFrame(wx.Frame):
> def PreCreate(self, pre):
> """ This function is called during the class's initialization.
>
> Override it for custom setup before the window is created
> usually to
> set additional window styles using SetWindowStyle() and
> SetExtraStyle()."""
> pass
>
> def __init__(self, parent):
> # Two stage creation (seehttp://wiki.wxpython.org/index.cgi/TwoSta...)
> pre = wx.PreFrame()
> self.PreCreate(pre)
> get_resources().LoadOnFrame(pre, parent, "MainFrame")
> self.PostCreate(pre)
>
> # create attributes for the named items in this container
> self.button = xrc.XRCCTRL(self, "button")
>
> # ------------------------ Resource data ----------------------
>
> def __init_resources():
> global __res
> __res = xrc.EmptyXmlResource()
>
> wx.FileSystem.AddHandler(wx.MemoryFSHandler())
>
> sbs_test_xrc = '''> <?xml version="1.0" ?><resource version="2.3.0.1" xmlns="http://www.wxwindows.org/wxxrc...
> <object class="wxDialog" name="Dialog">
> <style>wxDEFAULT_DIALOG_STYLE</style>
> <title/>
> <object class="wxFlexGridSizer">
> <rows>2</rows>
> <cols>2</cols>
> <vgap>0</vgap>
> <hgap>0</hgap>
> <growablecols/>
> <growablerows/>
> <object class="sizeritem">
> <option>1</option>
> <flag>wxEXPAND</flag>
> <border>5</border>
> <object class="wxStdDialogButtonSizer">
> <object class="button">
> <flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
> <border>5</border>
> <!--
> <object class="wxButton" name="wxID_OK">
> <label>&amp;OK</label>
> </object>
> -->
> <object class="wxButton" name="wxID_YES">
> <label>&amp;Yes</label>
> </object>
> </object>
> <object class="button">
> <flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
> <border>5</border>
> <!--
> <object class="wxButton" name="wxID_CANCEL">
> <label>&amp;Cancel</label>
> </object>
> -->
> <object class="wxButton" name="wxID_NO">
> <label>&amp;No</label>
> </object>
> </object>
> </object>
> </object>
> </object>
> </object>
> <object class="wxFrame" name="MainFrame">
> <style>wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL</style>
> <size>500,300</size>
> <title/>
> <object class="wxButton" name="button">
> <label>MyButton</label>
> <default>0</default>
> </object>
> </object>
> </resource>'''
>
> wx.MemoryFSHandler.AddFile('XRC/sbs_test/sbs_test_xrc',
> sbs_test_xrc)
> __res.Load('memory:XRC/sbs_test/sbs_test_xrc')

Nicola,

I've never created a modal dialog like this. Instead, I follow the
wxPython in Action book examples (most of the time), which would do a
yes/no dialog like this:

<code>

dlg = wx.MessageDialog(None, 'Some Message', 'A Message Box',
wx.YES_NO | wx.QUESTION)
retCode = dlg.ShowModal()
if retCode == wx.ID_YES:
# do something
print 'yes'
else:
# do something else
print 'no'
dlg.Destroy()

</code>

And I agree with Rob...there is a wxPython user's group, which is a
more appropriate place to post these types of questions. The Python
group will help all they can though.

Mike

Nicola Musatti

1/4/2008 9:35:00 AM

0

Hallo, Mike.
First of all, thanks to both you and Rob for your answers. I now see
that the wxPython group would have been a better place to post to, all
the more so given the tight connection between the wxPython and
wxWidgets projects, of which at first I wasn't aware.

On Jan 3, 8:19 pm, kyoso...@gmail.com wrote:
[...]
> I've never created a modal dialog like this. Instead, I follow the
> wxPython in Action book examples (most of the time), which would do a
> yes/no dialog like this:
>
> <code>
>
> dlg = wx.MessageDialog(None, 'Some Message', 'A Message Box',
> wx.YES_NO | wx.QUESTION)
> retCode = dlg.ShowModal()
> if retCode == wx.ID_YES:
> # do something
> print 'yes'
> else:
> # do something else
> print 'no'
> dlg.Destroy()
>
> </code>

Actually my example started out as something like

if wx.MessageBox(message="Some message", caption="Some caption",
style=wx.YES|wx.NO) == wx.YES:
pass

I had to change it because the actual message can become very long, so
I assembled a dialog with a scrollable text field. Maybe I'm expecting
to much of wxStdDialogButtonSizer, but I still feel that given that
both your method and mine above work straight away, it should provide
the same behaviour with Yes/No buttons as with OK/Cancel ones.

Cheers,
Nicola Musatti

Mike Driscoll

1/4/2008 2:12:00 PM

0

On Jan 4, 3:35 am, Nicola Musatti <nicola.musa...@gmail.com> wrote:
> Hallo, Mike.
> First of all, thanks to both you and Rob for your answers. I now see
> that the wxPython group would have been a better place to post to, all
> the more so given the tight connection between the wxPython and
> wxWidgets projects, of which at first I wasn't aware.
>
> On Jan 3, 8:19 pm, kyoso...@gmail.com wrote:
> [...]
>
>
>
> > I've never created a modal dialog like this. Instead, I follow the
> > wxPython in Action book examples (most of the time), which would do a
> > yes/no dialog like this:
>
> > <code>
>
> > dlg = wx.MessageDialog(None, 'Some Message', 'A Message Box',
> > wx.YES_NO | wx.QUESTION)
> > retCode = dlg.ShowModal()
> > if retCode == wx.ID_YES:
> > # do something
> > print 'yes'
> > else:
> > # do something else
> > print 'no'
> > dlg.Destroy()
>
> > </code>
>
> Actually my example started out as something like
>
> if wx.MessageBox(message="Some message", caption="Some caption",
> style=wx.YES|wx.NO) == wx.YES:
> pass
>
> I had to change it because the actual message can become very long, so
> I assembled a dialog with a scrollable text field. Maybe I'm expecting
> to much of wxStdDialogButtonSizer, but I still feel that given that
> both your method and mine above work straight away, it should provide
> the same behaviour with Yes/No buttons as with OK/Cancel ones.
>
> Cheers,
> Nicola Musatti

Nicola,

I have sub-classed wx.Dialog to do my own custom modal dialogs as
well. You can use sizers and put whatever widgets you want onto it
that way. Just make sure that when you create the Yes/No buttons, you
give them the wx.ID_YES or wx.ID_NO ids, rather than -1 or wx.ID_ANY.

yesBtn = wx.Button(parent, wx.ID_YES, 'Yes')
noBtn = wx.Button(parent, wx.ID_NO, 'No')

Mike

Nicola Musatti

1/4/2008 2:39:00 PM

0

On Jan 4, 3:12 pm, kyoso...@gmail.com wrote:
[...]
> I have sub-classed wx.Dialog to do my own custom modal dialogs as
> well. You can use sizers and put whatever widgets you want onto it
> that way. Just make sure that when you create the Yes/No buttons, you
> give them the wx.ID_YES or wx.ID_NO ids, rather than -1 or wx.ID_ANY.
>
> yesBtn = wx.Button(parent, wx.ID_YES, 'Yes')
> noBtn = wx.Button(parent, wx.ID_NO, 'No')

As far as I understand this should be taken care of by the XRC/
wxStdDialogButtonSizer combination.

Anyway, I solved my problem by binding the following event handler to
both buttons:

def OnButton(self, event):
if self.IsModal():
self.EndModal(event.GetId())

By the way, my assumption above appears to be supported by the fact
that a call to ShowModal() on my dialog does return wx.ID_YES when I
press the Yes button. I'm still a bit puzzled, but right now I can't
afford to let it bother me too much.

Thanks for your help!

Cheers,
Nicola