Sizer - horizontal/vertical expansion

I'm liking wxPython, just need a little help. This is a newbie question so
thank you for your patience. FYI I'm using version 2.3.

I want to layout controls on a page in rows - unequally sized. Each row
contains one or more widgets horizontally, but the entries do not form
columns. It's not a grid, just a collection of distinct input areas
(StaticBox) laid out in a row. There are multiple unrelated rows.

I want some of the input areas to take their sizes based on the size of the
containing panel. Others take their size based on the widgets that they
contain. I'm doing this by creating BoxSizers in a hierarchy. The rows are
horizontal BoxSizers containing one or more vertical BoxSizers. The rows are
brought together by a single vertical BoxSizer for the panel.

I have this working through trial and error and can get the whole thing to
expand by forcing one of the contained widgets to an arbitrary size, but I
want the whole thing to take on its size based on the size of the containing
panel. I can get this to work, but I'm having trouble ...

From the documentation on BoxSizer:

"The stretch factor ... is used for the main orientation, i.e. when using a
horizontal box sizer, the stretch factor determines how much the child can be
stretched horizontally."

... I'm having trouble getting the control placed in a horizontal BoxSizer to
limit its expansion to horizontal. The only way that I can get it to expand
at all is if when I add its row to the vertical BoxSizer (the one that brings
the rows together) I tell it that it can expand. That seems to tell it to
expand vertically as well. I don't want this.

First question: How can I get my row entry to expand horizontally only and
fill out to the size of the panel containing it?

Second question: In the following sample code, why does setting an explicit
size in the Frame produce something close to the desired result, but setting
the size on the Panel does not - seems to have no effect.

Please note: This is just sample that I put together to ask this question.
My real-world example is much more complex.

import wx

class TopFrame(wx.Frame):

    def __init__(self, parent, id, title):

···

#
# Two cases:
# - use the explict Frame size and the default size in the Panel (OK)
# - use the default Frame size and the explicit size in the Panel (NOT OK)
# wx.Frame.__init__(self, parent, id, title, (-1,-1), (-1, -1), \
        wx.Frame.__init__(self, parent, id, title, (-1,-1), (300, 150), \
                          wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER |
wx.RESIZE_BOX | wx.MAXIMIZE_BOX))

        mypanel = wx.Panel(self, -1, size = (-1,-1))
# mypanel = wx.Panel(self, -1, size = (300,150))

        mylabel1 = wx.StaticText(mypanel, label = "Label1", style =
wx.ALIGN_RIGHT)
        mytext1 = wx.TextCtrl(mypanel, size = (-1,-1))

        mylabel2 = wx.StaticText(mypanel, label = "Label2", style =
wx.ALIGN_RIGHT)
        mytext2 = wx.TextCtrl(mypanel, size = (-1,-1))

        mysizer1 = wx.BoxSizer(wx.HORIZONTAL)
        mysizer1.Add(mylabel1, 0, wx.CENTER)
        mysizer1.Add((5,5))
# If I don't expand here, I don't get expansion
# mysizer1.Add(mytext1, 0, wx.CENTER)
        mysizer1.Add(mytext1, 1, wx.CENTER|wx.EXPAND)

        mysizer2 = wx.BoxSizer(wx.HORIZONTAL)
        mysizer2.Add(mylabel2, 0, wx.CENTER)
        mysizer2.Add((5,5))
        mysizer2.Add(mytext2, 0, wx.CENTER)

        mysizer3 = wx.BoxSizer(wx.VERTICAL)
        mysizer3.AddSpacer((2,2), 0)
# If I don't expand here, I don't get expansion in either dimension
        mysizer3.Add(mysizer1, 1, wx.EXPAND)
# mysizer3.Add(mysizer1, 0)
        mysizer3.Add(mysizer2, 1)
        mysizer3.AddSpacer((1,1), 2, wx.EXPAND)

        mypanel.SetSizerAndFit(mysizer3)

class SPSApp(wx.App):

    def OnInit(self):
        self.topframe = TopFrame(None, -1, "TEST")
        self.SetTopWindow(self.topframe)
        self.topframe.Show(True)
        return True

app = SPSApp(redirect=True, filename = "testerror.log")
app.MainLoop()

__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005

Hi Todd,

I'm forwarding this message to wxPython-users, because a lot more people are viewing that list and so you'll get a lot more eyes on your problem there. You should come to wxPython-dev when you're pretty much certain there's a bug in wxPython.

Thanks,

Kevin

···

On Nov 1, 2005, at 12:41 PM, Todd Pravata wrote:

I'm liking wxPython, just need a little help. This is a newbie question so
thank you for your patience. FYI I'm using version 2.3.

I want to layout controls on a page in rows - unequally sized. Each row
contains one or more widgets horizontally, but the entries do not form
columns. It's not a grid, just a collection of distinct input areas
(StaticBox) laid out in a row. There are multiple unrelated rows.

I want some of the input areas to take their sizes based on the size of the
containing panel. Others take their size based on the widgets that they
contain. I'm doing this by creating BoxSizers in a hierarchy. The rows are
horizontal BoxSizers containing one or more vertical BoxSizers. The rows are
brought together by a single vertical BoxSizer for the panel.

I have this working through trial and error and can get the whole thing to
expand by forcing one of the contained widgets to an arbitrary size, but I
want the whole thing to take on its size based on the size of the containing
panel. I can get this to work, but I'm having trouble ...

From the documentation on BoxSizer:
"The stretch factor ... is used for the main orientation, i.e. when using a
horizontal box sizer, the stretch factor determines how much the child can be
stretched horizontally."

... I'm having trouble getting the control placed in a horizontal BoxSizer to
limit its expansion to horizontal. The only way that I can get it to expand
at all is if when I add its row to the vertical BoxSizer (the one that brings
the rows together) I tell it that it can expand. That seems to tell it to
expand vertically as well. I don't want this.

First question: How can I get my row entry to expand horizontally only and
fill out to the size of the panel containing it?

Second question: In the following sample code, why does setting an explicit
size in the Frame produce something close to the desired result, but setting
the size on the Panel does not - seems to have no effect.

Please note: This is just sample that I put together to ask this question.
My real-world example is much more complex.

import wx

class TopFrame(wx.Frame):

    def __init__(self, parent, id, title):
#
# Two cases:
# - use the explict Frame size and the default size in the Panel (OK)
# - use the default Frame size and the explicit size in the Panel (NOT OK)
# wx.Frame.__init__(self, parent, id, title, (-1,-1), (-1, -1), \
        wx.Frame.__init__(self, parent, id, title, (-1,-1), (300, 150), \
                          wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER |
wx.RESIZE_BOX | wx.MAXIMIZE_BOX))

        mypanel = wx.Panel(self, -1, size = (-1,-1))
# mypanel = wx.Panel(self, -1, size = (300,150))

        mylabel1 = wx.StaticText(mypanel, label = "Label1", style =
wx.ALIGN_RIGHT)
        mytext1 = wx.TextCtrl(mypanel, size = (-1,-1))

        mylabel2 = wx.StaticText(mypanel, label = "Label2", style =
wx.ALIGN_RIGHT)
        mytext2 = wx.TextCtrl(mypanel, size = (-1,-1))

        mysizer1 = wx.BoxSizer(wx.HORIZONTAL)
        mysizer1.Add(mylabel1, 0, wx.CENTER)
        mysizer1.Add((5,5))
# If I don't expand here, I don't get expansion
# mysizer1.Add(mytext1, 0, wx.CENTER)
        mysizer1.Add(mytext1, 1, wx.CENTER|wx.EXPAND)

        mysizer2 = wx.BoxSizer(wx.HORIZONTAL)
        mysizer2.Add(mylabel2, 0, wx.CENTER)
        mysizer2.Add((5,5))
        mysizer2.Add(mytext2, 0, wx.CENTER)

        mysizer3 = wx.BoxSizer(wx.VERTICAL)
        mysizer3.AddSpacer((2,2), 0)
# If I don't expand here, I don't get expansion in either dimension
        mysizer3.Add(mysizer1, 1, wx.EXPAND)
# mysizer3.Add(mysizer1, 0)
        mysizer3.Add(mysizer2, 1)
        mysizer3.AddSpacer((1,1), 2, wx.EXPAND)

        mypanel.SetSizerAndFit(mysizer3)

class SPSApp(wx.App):

    def OnInit(self):
        self.topframe = TopFrame(None, -1, "TEST")
        self.SetTopWindow(self.topframe)
        self.topframe.Show(True)
        return True

app = SPSApp(redirect=True, filename = "testerror.log")
app.MainLoop()

__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005
http://mail.yahoo.com

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-dev-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-dev-help@lists.wxwidgets.org

Note: you want to send this kind of question to wxPython-users instead of wxPython-dev.

Todd Pravata wrote:

I'm liking wxPython, just need a little help. This is a newbie question so
thank you for your patience. FYI I'm using version 2.3.

I doubt it. Perhaps Python 2.3? The latest wxPython is 2.6.1, and some folks are still using 2.4.2, and there are some 2.5.* versions floating around, which are really pre-cursors to 2.6

There were some sizer changes in 2.6, so this may be relevant.

I want some of the input areas to take their sizes based on the size of the
containing panel. Others take their size based on the widgets that they
contain. I'm doing this by creating BoxSizers in a hierarchy. The rows are
horizontal BoxSizers containing one or more vertical BoxSizers. The rows are
brought together by a single vertical BoxSizer for the panel.

This sounds right, but I don't quite get why you have Vertical sizers inside the horizontal sizers, but maybe you've got a more complicated layout than I think.

I have this working through trial and error and can get the whole thing to
expand by forcing one of the contained widgets to an arbitrary size, but I
want the whole thing to take on its size based on the size of the containing
panel.

That should be doable. Be careful with the wx.Window.fit() call, that makes the window fit what is inside it. You don't want that.

From the documentation on BoxSizer:
"The stretch factor ... is used for the main orientation, i.e. when using a
horizontal box sizer, the stretch factor determines how much the child can be
stretched horizontally."

yup.

... I'm having trouble getting the control placed in a horizontal BoxSizer to
limit its expansion to horizontal. The only way that I can get it to expand
at all is if when I add its row to the vertical BoxSizer (the one that brings
the rows together) I tell it that it can expand. That seems to tell it to
expand vertically as well. I don't want this.

no , you don't. You want to do something like this:

MyHorizSizer.Add(AWindow, 1 )
# this says that you want AWindow to stretch Horizontally
MyVertSizer.Add(MyHorizSizer, 0, wx.EXPAND)
# this says that you Don't want MyHorizsizer to stretch vertically, but Do want it to stretch horizontally.

Second question: In the following sample code, why does setting an explicit
size in the Frame produce something close to the desired result, but setting
the size on the Panel does not - seems to have no effect.

It makes no difference for me, it could be a platform or version difference: I'm using wxGTK 2.6.1

Please note: This is just sample that I put together to ask this question. My real-world example is much more complex.

Which brings up s good point: If you are putting a LOT of widgets on a Panel, chances are that they are grouped together in a way that they should really be custom classes, one for each group of widgets that works together. If you're nesting a lot of sizers, or you have a widget on a panel on p[panel on a frame, you should have multiple classes instead.

As a simple example, you've got a static text next to a text box, these could be grouped together into a class, subclassed from wx.Panel, that contains both. then you'd re-use this a bunch in your main Panel.

Some comments on your code:

        mypanel = wx.Panel(self, -1, size = (-1,-1))

If you're putting Panel on a Frame, why not have that Panel be its own class?

        mytext1 = wx.TextCtrl(mypanel, size = (-1,-1))

it's a good practice to use pre-defined constants like:

wx.ID_ANY, wx.DefaultSize and wx.DefaultPosition

        mysizer1.Add(mylabel1, 0, wx.CENTER)
        mysizer1.Add((5,5))

Do you want this space to expand? If not, you could also use a Border around your label instead:

mysizer1.Add(mylabel1, 0, wx.CENTER | wx.RIGHT, 5)

# mysizer1.Add(mytext1, 0, wx.CENTER)
        mysizer1.Add(mytext1, 1, wx.CENTER|wx.EXPAND)

There are two differences here. The "1" means expand Horizontally (in the direction of the Sizer), the wx.EXPAND means expand Vertically (across the direction of the sizer). I think you want the 1 and not the wxEXPAND here.

# If I don't expand here, I don't get expansion in either dimension
        mysizer3.Add(mysizer1, 1, wx.EXPAND)

Same as above, except hor. and ver. are reversed.

        mypanel.SetSizerAndFit(mysizer3)

Fit() means make the panel fit the controls it contains, you may not want that, and want just SetSizer() instead.

I think the diagram near the bottom of this page is very helpful:

http://wiki.wxpython.org/index.cgi/UsingSizers

-Good luck!

···

--
Christopher Barker, Ph.D.
Oceanographer
                                         
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Hi all,

I haven't gotten any mail from wxPython-users lately. Also, I just got a huge pile, all at once from wx-users, so I'm wondering if the list is malfunctioning. Is it working for any of you?

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer
                                         
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Hi Chris,

Chris Barker wrote:

Hi all,

I haven't gotten any mail from wxPython-users lately. Also, I just got a huge pile, all at once from wx-users, so I'm wondering if the list is malfunctioning. Is it working for any of you?

No problem here, I get my daily dose :slight_smile:

See you
Werner

···

-Chris

Werner F. Bruhin wrote:

No problem here, I get my daily dose :slight_smile:

Thanks, I guess I'll go re-subscribe. Strange.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer
                                         
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Already happened to me too, with wxPython and wx lists

Ricardo

···

On Tue, 2005-11-01 at 15:28 -0800, Chris Barker wrote:

Hi all,

I haven't gotten any mail from wxPython-users lately. Also, I just got a
huge pile, all at once from wx-users, so I'm wondering if the list is
malfunctioning. Is it working for any of you?

Hi Chris,

Hi all,

I haven't gotten any mail from wxPython-users lately. Also, I just got a huge pile, all at once from wx-users, so I'm wondering if the list is malfunctioning. Is it working for any of you?

I'm not on wxPython-users anymore, just too high-traffic for me to keep up with, but I did have a problem one time where the wx lists for some reason thought my email was no longer valid and stopped sending me things. Re-subscribing fixed it.

The huge pile to wx-users is probably a malfunction, but I don't know if anyone knows why it is malfunctioning or how to fix it. ;-/ We really should get to the bottom of it, although I think Robin was the person maintaining the lists.

Thanks,

Kevin

···

On Nov 1, 2005, at 3:28 PM, Chris Barker wrote:

-Chris

--
Christopher Barker, Ph.D.
Oceanographer

NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-dev-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-dev-help@lists.wxwidgets.org