Autopositioning of buttons using StdDialogButtonSizer only works for some buttons

Hi,

It seems the autopositioning of buttons using StdDialogButtonSizer only works for some buttons.

Reading the documentation (http://www.wxpython.org/docs/api/wx.StdDialogButtonSizer-class.html) ...

    "A special sizer that knows how to order and position standard
    buttons in order to conform to the current platform's standards. You
    simply need to add each wx.Button to the sizer, and be sure to
    create the buttons using the standard ID's. Then call Realize and
    the sizer will take care of the rest."

... I was hoping I could just feed the special sizer the buttons and layout would be taken care of. As you will hopefully see from the attached script, this was not so. All but a few buttons ended up stacked on top of each other. The problem occurs not only in v2.8.8.0 (gtk2-unicode) on Ubuntu Intrepid but also on my Windows XP system.

The example script has a handful of buttons which I give to the StdDialogButtonSizer using AddButton. After this I run Realize().

I was unable to solve the problem by using the Dialog rather than Frame object or by dropping the panel (when using a Dialog).

If you change manual_pos from True to False you should see the problem. BTW the buttons themselves are lovely when you can see them ;-).

  import wx

"""
http://www.wxpython.org/docs/api/wx.Button-class.html
e.g.
wx.ID_CANCEL '&Cancel'
wx.ID_CLOSE '&Close'
wx.ID_DELETE '&Delete'
wx.ID_EDIT '&Edit'
wx.ID_FILE '&File'
"""

manual_pos = True # change to False to see problem

class AutoPosFrame(wx.Frame):
    """
    Buttons display properly.
    All buttons are provided to StdDialogButtonSizer for automatic
        positioning.
    """
    def __init__(self):
        wx.Frame.__init__(self, None, -1)
        panel = wx.Panel(self, -1)
        btnEdit = wx.Button(panel, wx.ID_EDIT)
        btnCancel = wx.Button(panel, wx.ID_CANCEL)
        btnDelete = wx.Button(panel, wx.ID_DELETE)
        btnSave = wx.Button(panel, wx.ID_SAVE)
        btnClose = wx.Button(panel, wx.ID_CLOSE)
        btnFind = wx.Button(panel, wx.ID_FIND) szrButtons = wx.StdDialogButtonSizer()
        # ALL to be autopositoned
        szrButtons.AddButton(btnFind)
        szrButtons.AddButton(btnClose)
        szrButtons.AddButton(btnDelete)
        szrButtons.AddButton(btnEdit)
        szrButtons.AddButton(btnCancel)
        szrButtons.AddButton(btnSave)
        szrButtons.Realize()
        panel.SetSizer(szrButtons)
        szrButtons.SetSizeHints(self)
        self.Layout()

class ManualPosFrame(wx.Frame):
    """
    Buttons display properly.
    All but Cancel and Save are manually positioned into sizer.
    """
    def __init__(self):
        "Buttons display properly but only Cancel and Save are autopositioned"
        wx.Frame.__init__(self, None, -1)
        panel = wx.Panel(self, -1)
        btnEdit = wx.Button(panel, wx.ID_EDIT)
        btnCancel = wx.Button(panel, wx.ID_CANCEL)
        btnDelete = wx.Button(panel, wx.ID_DELETE)
        btnSave = wx.Button(panel, wx.ID_SAVE)
        btnClose = wx.Button(panel, wx.ID_CLOSE)
        btnFind = wx.Button(panel, wx.ID_FIND) szrButtons = wx.StdDialogButtonSizer()
        szrTopButtons = wx.BoxSizer(wx.HORIZONTAL)
        szrTopButtons.Add(btnFind)
        szrTopButtons.Add(btnClose)
        szrTopButtons.Add(btnDelete)
        szrTopButtons.Add(btnEdit)
        szrButtons.Add(szrTopButtons)
        szrButtons.AddButton(btnCancel) # to be autopositoned
        szrButtons.AddButton(btnSave) # to be autopositoned
        szrButtons.Realize()
        panel.SetSizer(szrButtons)
        szrButtons.SetSizeHints(self)
        self.Layout()

app = wx.PySimpleApp()
if manual_pos:
    frame = ManualPosFrame()
else:
    frame = AutoPosFrame()
frame.Show()
app.MainLoop()

···

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

In the past I never noticed this problem because I only used Close, OK, Cancel, and Save - all of which are positioned correctly IIRC.

All the best, Grant

Grant Paton-Simpson wrote:

Hi,

It seems the autopositioning of buttons using StdDialogButtonSizer only works for some buttons.

Reading the documentation (wxPython API Documentation — wxPython Phoenix 4.2.2 documentation) ...

   "A special sizer that knows how to order and position standard
   buttons in order to conform to the current platform's standards. You
   simply need to add each wx.Button to the sizer, and be sure to
   create the buttons using the standard ID's. Then call Realize and
   the sizer will take care of the rest."

What the docs don't say very clearly is that this is for buttons that would normally appear on standard dialogs, not necessarily for all buttons with a standard ID on any dialog. The IDs which will be managed by the sizer are:

         wx.ID_OK
         wx.ID_YES
         wx.ID_SAVE
         wx.ID_APPLY
         wx.ID_NO
         wx.ID_CANCEL
         wx.ID_HELP
         wx.ID_CONTEXT_HELP

···

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