[wxPython] Nested sizers problem

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[wxPython] Nested sizers problem

Amos Latteier-2
Hi,

Firstly let me thank Robin Dunn for wxPython, it's great! I've been amazed
at how easy it is for me to build powerful user interfaces.

I am trying to understand sizers. I can build one fine, but when I try to
place windows with sizers *inside* other sizers I'm having problems. To
illustrate my point here is a program:

from wxPython.wx import *

class MyPanel(wxPanel):
    def __init__(self, parent, id):
        wxPanel.__init__(self, parent, id,
                         wxDefaultPosition, wxDefaultSize,
                         style=wxSIMPLE_BORDER)
        self.box=wxBoxSizer(wxHORIZONTAL)
        self.box.Add(wxButton(self, -1, 'Foo'), 1, wxEXPAND)
        self.box.Add(wxButton(self, -1, 'Bar'), 1, wxEXPAND)
        self.box.Add(wxButton(self, -1, 'Bot'), 1, wxEXPAND)
        self.SetAutoLayout(true)
        self.SetSizer(self.box)
        self.box.Fit(self)
        self.box.SetSizeHints(self)
       
class MyFrame(wxFrame):
    def __init__(self, parent, id, title):
        wxFrame.__init__(self, parent, -1, title,
                         wxDefaultPosition, wxSize(300, 400))
        self.box=wxBoxSizer(wxVERTICAL)
        self.box.Add(MyPanel(self, -1), 1, wxEXPAND)
        self.box.Add(MyPanel(self, -1), 1, wxEXPAND)
        self.SetAutoLayout(true)
        self.SetSizer(self.box)
        self.box.Fit(self)
        self.box.SetSizeHints(self)

class MyApp(wxApp):
    def OnInit(self):
        frame = MyFrame(None, -1, title="Sizer Test")
        self.SetTopWindow(frame)
        frame.Show(TRUE)
        return TRUE

if __name__ == '__main__':
    app = MyApp(0)
    app.MainLoop()

--

The outer sizer (on the frame) works correctly and constrains the two inner
panels just fine. The problem is that the sizers on the inner panels don't
seem to work correctly. The panel's three buttons are drawn on top of each
other, though the panel seems to allocate enough space to hold them side by
side. You can see that the buttons are on top of each other because when
you click on them sometimes another button appears in place of the one you
clicked on.

Any advice is most appreciated. Since I'm new to wxPython I may be going
about things backwards.

-Amos

P.S. I'm using NT, and wxPython 2.1.4.



_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] Nested sizers problem

Robin Dunn
> Hi,
>
> Firstly let me thank Robin Dunn for wxPython, it's great! I've been amazed
> at how easy it is for me to build powerful user interfaces.
>
> I am trying to understand sizers. I can build one fine, but when I try to
> place windows with sizers *inside* other sizers I'm having problems. To
> illustrate my point here is a program:
>
[...]
>
> The outer sizer (on the frame) works correctly and constrains the two
inner
> panels just fine. The problem is that the sizers on the inner panels don't
> seem to work correctly. The panel's three buttons are drawn on top of each
> other, though the panel seems to allocate enough space to hold them side
by
> side. You can see that the buttons are on top of each other because when
> you click on them sometimes another button appears in place of the one you
> clicked on.
>
> Any advice is most appreciated. Since I'm new to wxPython I may be going
> about things backwards.
>

I've never tried this on non-top-level windows so I never noticed it, but
apparently only top-level windows (wxFrame, wxDialog, etc.) have a default
EVT_SIZE handler and respond to SetAutoLayout.  I don't agree with this but
untile the wxWindows core changes you can fix this by doing it yourself,
(SetAutoLayout is just a convenience anyway.)  Here is a new MyPanel for
you:

class MyPanel(wxPanel):
    def __init__(self, parent, id):
        wxPanel.__init__(self, parent, id,
                         wxDefaultPosition, wxDefaultSize,
                         style=wxSIMPLE_BORDER)
        self.box=wxBoxSizer(wxHORIZONTAL)
        self.box.Add(wxButton(self, -1, 'Foo'), 1, wxEXPAND)
        self.box.Add(wxButton(self, -1, 'Bar'), 1, wxEXPAND)
        self.box.Add(wxButton(self, -1, 'Bot'), 1, wxEXPAND)
        self.SetSizer(self.box)
        EVT_SIZE(self, self.OnSize)

    def OnSize(self, evt):
        self.Layout()

Notice that I also removed the Fit and SetSizeHints since they are not
really necessary since the frame is already sizing the panels for you, they
don't need to try and size themselves.

--
Robin Dunn
Software Craftsman
[hidden email]
http://AllDunn.com/robin/
http://AllDunn.com/wxPython/  Check it out!



_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] Nested sizers problem

Robin Dunn
>
> Notice that I also removed the Fit and SetSizeHints since they are not
> really necessary since the frame is already sizing the panels for you,
they
> don't need to try and size themselves.
>

Actually, I spoke a little too soon here.  If you want the buttons to start
off ant their default sizes then you'll want to keep the Fit() in there.
Otherwise your initial size will be minimal.

--
Robin Dunn
Software Craftsman
[hidden email]
http://AllDunn.com/robin/
http://AllDunn.com/wxPython/  Check it out!




_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users