Help with layout.

Hello,

I'm new to wxPython and I'm struggling with wx.BoxSizer. The problem
is that all my widgets expand to take up the entire space available
and it looks horrible. For example:

myHSizer.Add(wx.Button(self, wx.ID_ANY, "Clear"),1,wx.EXPAND)

Here the "Clear" button expands, making the button a lot bigger than
the word "Clear". So the button looks wrong, and all the widgets are
touching each other. I have this problem with all widgets. I really
prefer the way things look on Gtk. Gtk is simple to use and the
widgets look right by default. Why can't WX do that?

Anyways, after struggling to find something about this on the
documentation I found about wx.ALL and wx.CENTER. I tried using those.
wx.ALL at improves things a little because at least the widgets are
not touching anymore, but I think it is totally the wrong way to look
at the problem. I don't want to put "x" pixels around the button. I
want the button to be a reasonable size based on its contents and have
the toolkit figure out how to space it properly.

Any ideas?

For completeness, I include demo source code of the application I want
to write:

···

####
# Daniel's dictionary application.
#
import wx

class MainWindow(wx.Frame):
  def __init__(self, parent, id, title):
    wx.Frame.__init__(self, parent, id, title, size=(300,200))

    self.CreateStatusBar()
    self.mySetContents()
    self.mySetMenuBar()

    self.Show(True)

  #
  # Main contents
  #
  def mySetContents(self):
    # Boxes.
    topHbox = wx.BoxSizer(wx.HORIZONTAL)
    rightCol = wx.BoxSizer(wx.VERTICAL)
    searchTerm = wx.BoxSizer(wx.HORIZONTAL)

    # Radio buttons.
    radioList = ['English -> German', 'German -> English']
    radioBox = wx.RadioBox(self, wx.ID_ANY, "", wx.DefaultPosition,
          wx.DefaultSize, radioList, 2, wx.RA_SPECIFY_ROWS)

    #
    # Search entry.
    #
    searchTerm.Add(wx.TextCtrl(self, wx.ID_ANY),2,wx.ALL|wx.CENTER,5)
    searchTerm.Add(wx.Button(self, wx.ID_ANY, "Clear"),1,wx.ALL|
wx.CENTER,5)

    #
    # Search entry and output.
    #
    rightCol.Add(searchTerm,1,wx.EXPAND)
    rightCol.Add(wx.StaticText(self, wx.ID_ANY, 'Foo'),4,wx.ALL|
wx.CENTER,5)

    #
    # Everything.
    #
    topHbox.Add(radioBox,1,wx.EXPAND)
    topHbox.Add(rightCol,2,wx.EXPAND)

    # Finish.
    self.SetSizer(topHbox)
    self.SetAutoLayout(1)
    topHbox.Fit(self)

  #
  # Menu Bar
  #
  def mySetMenuBar(self):
    # Setup menus.
    fileMenu = wx.Menu()
    fileMenu.Append(wx.ID_ANY, "E&xit","Terminate program.")

    helpMenu = wx.Menu()
    helpMenu.Append(wx.ID_ANY, "&Contents", "Open manual")
    helpMenu.AppendSeparator()
    helpMenu.Append(wx.ID_ANY, "&About", "Information about this
program.")

    # Create menu bar.
    menuBar = wx.MenuBar()
    menuBar.Append(fileMenu, "&File")
    menuBar.Append(helpMenu, "&Help")

    # Menus done.
    self.SetMenuBar(menuBar)

app = wx.PySimpleApp()
frame = MainWindow(None, wx.ID_ANY, "My Dictionary")
app.MainLoop()

Hi,

Hello,

I'm new to wxPython and I'm struggling with wx.BoxSizer. The problem
is that all my widgets expand to take up the entire space available
and it looks horrible. For example:

myHSizer.Add(wx.Button(self, wx.ID_ANY, "Clear"),1,wx.EXPAND)

Here the "Clear" button expands, making the button a lot bigger than
the word "Clear". So the button looks wrong, and all the widgets are
touching each other. I have this problem with all widgets. I really
prefer the way things look on Gtk. Gtk is simple to use and the
widgets look right by default. Why can't WX do that?

Anyways, after struggling to find something about this on the
documentation I found about wx.ALL and wx.CENTER. I tried using those.
wx.ALL at improves things a little because at least the widgets are
not touching anymore, but I think it is totally the wrong way to look
at the problem. I don't want to put "x" pixels around the button. I
want the button to be a reasonable size based on its contents and have
the toolkit figure out how to space it properly.

Any ideas?

Look at the parameters for sizer.Add. Add(window, proportion, flags, ...)

You are telling the sizer to give the window a proportion of 1 and are
using the EXPAND flag, which tells the sizer to stretch the window to
fill all the space.

Don't use a value greater than 0 for the proportion unless you want to
window to take up more space, and don't use the EXPAND flag unless you
want the window to expand.

Cody

···

On Tue, Jan 12, 2010 at 6:22 AM, Daniel Carrera <dcarrera@gmail.com> wrote:

Hi Dan,
Try the attached and see if it is more like what you need!

Steve

dans.py (2.14 KB)

···

--------------------------------------------------
From: "Daniel Carrera" <dcarrera@gmail.com>
Sent: Tuesday, January 12, 2010 12:22 PM
To: "wxPython-users" <wxpython-users@googlegroups.com>
Subject: [wxPython-users] Help with layout.

Hello,

I'm new to wxPython and I'm struggling with wx.BoxSizer. The problem
is that all my widgets expand to take up the entire space available
and it looks horrible. For example:

myHSizer.Add(wx.Button(self, wx.ID_ANY, "Clear"),1,wx.EXPAND)

Here the "Clear" button expands, making the button a lot bigger than
the word "Clear". So the button looks wrong, and all the widgets are
touching each other. I have this problem with all widgets. I really
prefer the way things look on Gtk. Gtk is simple to use and the
widgets look right by default. Why can't WX do that?

Anyways, after struggling to find something about this on the
documentation I found about wx.ALL and wx.CENTER. I tried using those.
wx.ALL at improves things a little because at least the widgets are
not touching anymore, but I think it is totally the wrong way to look
at the problem. I don't want to put "x" pixels around the button. I
want the button to be a reasonable size based on its contents and have
the toolkit figure out how to space it properly.

Any ideas?

For completeness, I include demo source code of the application I want
to write:

####
# Daniel's dictionary application.
#
import wx

class MainWindow(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(300,200))

self.CreateStatusBar()
self.mySetContents()
self.mySetMenuBar()

self.Show(True)

#
# Main contents
#
def mySetContents(self):
# Boxes.
topHbox = wx.BoxSizer(wx.HORIZONTAL)
rightCol = wx.BoxSizer(wx.VERTICAL)
searchTerm = wx.BoxSizer(wx.HORIZONTAL)

# Radio buttons.
radioList = ['English -> German', 'German -> English']
radioBox = wx.RadioBox(self, wx.ID_ANY, "", wx.DefaultPosition,
wx.DefaultSize, radioList, 2, wx.RA_SPECIFY_ROWS)

#
# Search entry.
#
searchTerm.Add(wx.TextCtrl(self, wx.ID_ANY),2,wx.ALL|wx.CENTER,5)
searchTerm.Add(wx.Button(self, wx.ID_ANY, "Clear"),1,wx.ALL|
wx.CENTER,5)

#
# Search entry and output.
#
rightCol.Add(searchTerm,1,wx.EXPAND)
rightCol.Add(wx.StaticText(self, wx.ID_ANY, 'Foo'),4,wx.ALL|
wx.CENTER,5)

#
# Everything.
#
topHbox.Add(radioBox,1,wx.EXPAND)
topHbox.Add(rightCol,2,wx.EXPAND)

# Finish.
self.SetSizer(topHbox)
self.SetAutoLayout(1)
topHbox.Fit(self)

#
# Menu Bar
#
def mySetMenuBar(self):
# Setup menus.
fileMenu = wx.Menu()
fileMenu.Append(wx.ID_ANY, "E&xit","Terminate program.")

helpMenu = wx.Menu()
helpMenu.Append(wx.ID_ANY, "&Contents", "Open manual")
helpMenu.AppendSeparator()
helpMenu.Append(wx.ID_ANY, "&About", "Information about this
program.")

# Create menu bar.
menuBar = wx.MenuBar()
menuBar.Append(fileMenu, "&File")
menuBar.Append(helpMenu, "&Help")

# Menus done.
self.SetMenuBar(menuBar)

app = wx.PySimpleApp()
frame = MainWindow(None, wx.ID_ANY, "My Dictionary")
app.MainLoop()

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

Hello,

I'm new to wxPython

Welcome.

and I'm struggling with wx.BoxSizer. The problem
is that all my widgets expand to take up the entire space available
and it looks horrible. For example:

myHSizer.Add(wx.Button(self, wx.ID_ANY, "Clear"),1,wx.EXPAND)

Here the "Clear" button expands, making the button a lot bigger than
the word "Clear". So the button looks wrong, and all the widgets are
touching each other. I have this problem with all widgets. I really
prefer the way things look on Gtk. Gtk is simple to use and the
widgets look right by default. Why can't WX do that?

The way you used the wxBoxSizer was actually not the default--you
specified that you wanted the button to expand by using the wx.EXPAND
flag. And it did what you specified. As Cody mentioned, you also set
the proportion to something other than 0, which will also make the widget
take up the available room when its parent area is made larger.

Anyways, after struggling to find something about this on the
documentation

I'm not sure why it was a struggle. If you just put "wxboxsizer" into
Google, the first link is the docs for it, which includes a section on
"Programming with wxBoxSizer", that touches on (though I admit
doesn't describe very thoroughly) your issues. But the third link
from Google, "What do these sizer things do?" is a nice overview,
and right on that first page of it you see the solution you want. If
you search for "wxPython sizers" you can find a number of other
good tutorials, including this nice one by frequent list poster
here, Mike:

Andrea has also written something that might be useful to play with
to get the hang of sizers:

http://xoomer.virgilio.it/infinity77/main/SizerHack.html

Sizers are kind of unintuitive at first, but it just takes getting a little
practice with the ideas.

Che

···

On Tue, Jan 12, 2010 at 7:22 AM, Daniel Carrera <dcarrera@gmail.com> wrote:

C M wrote:

The way you used the wxBoxSizer was actually not the default--you
specified that you wanted the button to expand by using the wx.EXPAND
flag.

The tutorial on the website uses wx.EXPAND. In any case, I tried without wx.EXPAND as well. I also tried with wx.ALL and wx.CENTER.

And it did what you specified.

In the strictest sense, computers always do what you specify, even if they don't do what you want.

I'm not sure why it was a struggle. If you just put "wxboxsizer" into
Google, the first link is the docs for it, which includes a section on
"Programming with wxBoxSizer", that touches on (though I admit
doesn't describe very thoroughly) your issues.

I did find this page, and it didn't help me. This is the API reference. I think it is terse and not easy to understand. I also looked all over the tutorials.

Notice that after the help from you and other posters I still can't manage to get the window to look right - but Steve's version was a good improvement! (thanks Steve!).

Steve's version also gave me a better idea of what things to change, so I've made some more improvements of my own. That said, I have some notes and issues:

1) I don't want the radio buttons and the other widgets to expand vertically when I make the window taller. I found how to do this:

    topHbox.Add(radioBox,0,wx.ALL,5)
    topHbox.Add(rightCol,0,wx.ALL,5)

It just seems odd that the vertical behaviour of a window be based on how you put widgets into a horizontal box.

2) Adding wx.CENTER to the above, does not cause the radioBox and rightCol boxes to be centred horizontally. If I make the window size larger, they are centred vertically. This is very odd.

3) The button size is more reasonable now, but the text box is strangely small. In particular, the button and the text box are the same size. That seems very odd, and I don't know how to change it.

searchTerm = wx.BoxSizer(wx.HORIZONTAL) searchTerm.Add(wx.TextCtrl(self,wx.ID_ANY),1,wx.ALL|wx.CENTER,5)
searchTerm.Add(wx.Button(self, wx.ID_ANY,"Clear"),0,wx.ALL|wx.CENTER,5)

I tried using 0 or 1 for the control box, and I tried adding wx.EXPAND, but it makes no difference. I suspect that the sizer 'searchTerm' itself is not expanding, but using:

rightCol.Add(searchTerm,1,wx.ALL|wx.CENTER|wx.EXPAND)

Makes no difference. That might mean that 'rightCol' itself is not expanding. But if I use:

topHbox.Add(rightCol,1,wx.ALL|wx.CENTER|wx.EXPAND,5)

That actually causes the text box to expand only vertically! So I can't actually make it expand horizontally...

http://www.blog.pythonlibrary.org/2008/05/18/a-wxpython-sizers-tutorial/

Thanks. I'll read that today.

Sizers are kind of unintuitive at first, but it just takes getting a little
practice with the ideas.

Indeed.

Sorry to compare with another widget, but I didn't have this much difficulty with Gtk. I'm trying wx anyways because I'd like the app to be cross platform. My understanding is that wx will look more native in non-Linux platforms.

Daniel.

C M wrote:
> The way you used the wxBoxSizer was actually not the default--you
> specified that you wanted the button to expand by using the wx.EXPAND
> flag.

The tutorial on the website uses wx.EXPAND. In any case, I tried without
wx.EXPAND as well. I also tried with wx.ALL and wx.CENTER.

Which tutorial? Maybe I can explain what it's doing...

1) I don't want the radio buttons and the other widgets to expand
vertically when I make the window taller. I found how to do this:

topHbox\.Add\(radioBox,0,wx\.ALL,5\)
topHbox\.Add\(rightCol,0,wx\.ALL,5\)

It just seems odd that the vertical behaviour of a window be based on
how you put widgets into a horizontal box.

The vertical behavior was caused because you added the widgets to
rightCol with EXPAND set. That contained most of the widgets. When you
told the parent sizer (i.e. topHbox) to EXPAND, that told it to go
ahead and apply the settings you had in the child sizer (i.e.
rightCol). It should now expand in BOTH directions.

2) Adding wx.CENTER to the above, does not cause the radioBox and
rightCol boxes to be centred horizontally. If I make the window size
larger, they are centred vertically. This is very odd.

3) The button size is more reasonable now, but the text box is strangely
small. In particular, the button and the text box are the same size.
That seems very odd, and I don't know how to change it.

searchTerm = wx.BoxSizer(wx.HORIZONTAL)
searchTerm.Add(wx.TextCtrl(self,wx.ID_ANY),1,wx.ALL|wx.CENTER,5)
searchTerm.Add(wx.Button(self, wx.ID_ANY,"Clear"),0,wx.ALL|wx.CENTER,5)

I tried using 0 or 1 for the control box, and I tried adding wx.EXPAND,
but it makes no difference. I suspect that the sizer 'searchTerm' itself
is not expanding, but using:

rightCol.Add(searchTerm,1,wx.ALL|wx.CENTER|wx.EXPAND)

Makes no difference. That might mean that 'rightCol' itself is not
expanding. But if I use:

topHbox.Add(rightCol,1,wx.ALL|wx.CENTER|wx.EXPAND,5)

That actually causes the text box to expand only vertically! So I can't
actually make it expand horizontally...

>http://www.blog.pythonlibrary.org/2008/05/18/a-wxpython-sizers-tutorial/

Thanks. I'll read that today.

> Sizers are kind of unintuitive at first, but it just takes getting a little
> practice with the ideas.

Indeed.

Sorry to compare with another widget, but I didn't have this much
difficulty with Gtk. I'm trying wx anyways because I'd like the app to
be cross platform. My understanding is that wx will look more native in
non-Linux platforms.

Daniel.

If you still have issues after reading all that, go ahead and post the
code to here (preferably as an attachment or a link to a paste like
http://paste.pocoo.org/) and tell us what you want it to do. Maybe we
can figure it out.

···

On Jan 12, 1:53 pm, Daniel Carrera <dcarr...@gmail.com> wrote:

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org

PyCon 2010 Atlanta Feb 19-21 http://us.pycon.org/

Hi,

Steve's version also gave me a better idea of what things to change, so I've
made some more improvements of my own. That said, I have some notes and
issues:

1) I don't want the radio buttons and the other widgets to expand vertically
when I make the window taller. I found how to do this:

topHbox.Add(radioBox,0,wx.ALL,5)
topHbox.Add(rightCol,0,wx.ALL,5)

It just seems odd that the vertical behaviour of a window be based on how
you put widgets into a horizontal box.

Yes but you then put your horizontal sizer into a vertical sizer which
will apply vertical oriented sizing to all that sizers children.

2) Adding wx.CENTER to the above, does not cause the radioBox and rightCol
boxes to be centred horizontally. If I make the window size larger, they are
centred vertically. This is very odd.

As above when adding an item to the vertical sizer the centering will
be applied to that orientation, you also need to apply it to the sizer
that handles the horizontal sizing to get it to work in both
orientations.

3) The button size is more reasonable now, but the text box is strangely
small. In particular, the button and the text box are the same size. That
seems very odd, and I don't know how to change it.

You can set size hints, initial size, min size, etc.. for control this

searchTerm = wx.BoxSizer(wx.HORIZONTAL)
searchTerm.Add(wx.TextCtrl(self,wx.ID_ANY),1,wx.ALL|wx.CENTER,5)
searchTerm.Add(wx.Button(self, wx.ID_ANY,"Clear"),0,wx.ALL|wx.CENTER,5)

I tried using 0 or 1 for the control box, and I tried adding wx.EXPAND, but
it makes no difference. I suspect that the sizer 'searchTerm' itself is not
expanding, but using:

rightCol.Add(searchTerm,1,wx.ALL|wx.CENTER|wx.EXPAND)

Makes no difference. That might mean that 'rightCol' itself is not
expanding. But if I use:

topHbox.Add(rightCol,1,wx.ALL|wx.CENTER|wx.EXPAND,5)

That actually causes the text box to expand only vertically! So I can't
actually make it expand horizontally...

This is because you passed 1 proportion and EXPAND to the vertical
sizer when you added the searchTerm. Which tells it to expand
searchTerm vertically to fill the space.

See attached augmented sample.

Cody

dans_2.py (2.54 KB)

···

On Tue, Jan 12, 2010 at 1:53 PM, Daniel Carrera <dcarrera@gmail.com> wrote:

Listen to Cody...I think I may have mis-written some of my responses
and I don't want to add to the confusion.

···

On Jan 12, 2:43 pm, Cody Precord <codyprec...@gmail.com> wrote:

Hi,

On Tue, Jan 12, 2010 at 1:53 PM, Daniel Carrera <dcarr...@gmail.com> wrote:

> Steve's version also gave me a better idea of what things to change, so I've
> made some more improvements of my own. That said, I have some notes and
> issues:

> 1) I don't want the radio buttons and the other widgets to expand vertically
> when I make the window taller. I found how to do this:

> topHbox.Add(radioBox,0,wx.ALL,5)
> topHbox.Add(rightCol,0,wx.ALL,5)

> It just seems odd that the vertical behaviour of a window be based on how
> you put widgets into a horizontal box.

Yes but you then put your horizontal sizer into a vertical sizer which
will apply vertical oriented sizing to all that sizers children.

> 2) Adding wx.CENTER to the above, does not cause the radioBox and rightCol
> boxes to be centred horizontally. If I make the window size larger, they are
> centred vertically. This is very odd.

As above when adding an item to the vertical sizer the centering will
be applied to that orientation, you also need to apply it to the sizer
that handles the horizontal sizing to get it to work in both
orientations.

> 3) The button size is more reasonable now, but the text box is strangely
> small. In particular, the button and the text box are the same size. That
> seems very odd, and I don't know how to change it.

You can set size hints, initial size, min size, etc.. for control this

> searchTerm = wx.BoxSizer(wx.HORIZONTAL)
> searchTerm.Add(wx.TextCtrl(self,wx.ID_ANY),1,wx.ALL|wx.CENTER,5)
> searchTerm.Add(wx.Button(self, wx.ID_ANY,"Clear"),0,wx.ALL|wx.CENTER,5)

> I tried using 0 or 1 for the control box, and I tried adding wx.EXPAND, but
> it makes no difference. I suspect that the sizer 'searchTerm' itself is not
> expanding, but using:

> rightCol.Add(searchTerm,1,wx.ALL|wx.CENTER|wx.EXPAND)

> Makes no difference. That might mean that 'rightCol' itself is not
> expanding. But if I use:

> topHbox.Add(rightCol,1,wx.ALL|wx.CENTER|wx.EXPAND,5)

> That actually causes the text box to expand only vertically! So I can't
> actually make it expand horizontally...

This is because you passed 1 proportion and EXPAND to the vertical
sizer when you added the searchTerm. Which tells it to expand
searchTerm vertically to fill the space.

See attached augmented sample.

Cody

dans_2.py
3KViewDownload

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org

PyCon 2010 Atlanta Feb 19-21 http://us.pycon.org/

I did find this page, and it didn't help me. This is the API reference. I
think it is terse and not easy to understand. I also looked all over the
tutorials.

It's not easy to understand, but I think that is the concept more than the
writing, probably because sizers are such a visuospatial thing and
describing them in words is inherently challenging. But this section
from "Programming with wxBoxSizer" may be most applicable for your
concerns, so maybe a bit more commentary/clarification of it can be
helpful--I've broken up this long paragraph for clarity and added my
comments in brackets:

···

---------

"It is the unique feature of a box sizer, that it can grow in both
directions (height
and width) but can distribute its growth in the main direction
(horizontal for a row)
*unevenly* among its children."

[This is the first part of what you want--the ability to make *some
but not all*
windows grow in the main direction. Here "grow in the main direction" means
horizontally for a horizontal box sizer, vertically for a vertical box sizer.]

"In our example case, the vertical sizer is supposed to propagate all
its height
changes to only the text area, not to the button area. This is
determined by the
*proportion parameter* when adding a window (or another sizer) to a
sizer. It is
interpreted as a weight factor, i.e. *** it can be zero, indicating
that the window may
not be resized at all *** "

[There's what you need. 0 proportion parameter means no resizing in the main
direction...that is, horizontally for a horizontal box sizer,
vertically for a vertical one]

", or above zero. If several windows have a value above zero, the
value is interpreted
relative to the sum of all weight factors of the sizer, so when adding
two windows with
a value of 1, they will both get resized equally much and each half as
much as the sizer
owning them. "

[e.g. if I wanted a big text box to take up 2/3 of the available size,
and a panel the
remaining third, I'd give the big text box a proportion parameter of 2
and the panel
a proportion parameter of 1. The sum of 2 + 1 = 3, and so the big text box got
2 out of 3 (2/3) and the panel just got 1 out of 3 (1/3). As the whole window is
resized, these two components will maintain that proportionality.]

[now on to the part about wx.EXPAND...]

"Then what do we do when a column sizer changes its width?"

[now they are addressing the "non-main" direction. I.e. the vertical
for a horizontal
boxsizer, etc. It's confusing that they are referring to them as
"column sizer" or
"row sizer", I agree.]

"This behaviour is controlled by *flags* (the second parameter of the
Add() function):
Zero or no flag indicates that the window will preserve it is original size,"

[note: in that *non-main* direction. This is part two of what you needed.]

"wxGROW flag (same as wxEXPAND) forces the window to grow with the sizer,"

[again, in that *non-main* direction]

-----------

My understanding is that wx will look more native in non-Linux
platforms.

That's right. It should look native.

Lastly, it is good to note that often if you make changes to sizers
you often have
to call Layout() on the panel that contains the objects to be sized.
One good way
to see if you need to do that is to run your app, then manually expand the frame
by dragging a corner, and if things suddenly resize, you know you'll need to use
Layout after all the sizing rules are set up.

Che

Che

Sorry about that awful formatting of that last message. Let me try again...

I did find this page, and it didn't help me. This is the API
reference. I think it is terse and not easy to understand.

It's not easy to understand, but I think that is the concept more than
the writing, probably because sizers are such a visuospatial thing and
describing them in words is inherently challenging. But this section
from "Programming with wxBoxSizer" may be most applicable for your
concerns, so maybe a bit more commentary/clarification of it can be
helpful--I've broken up this long paragraph for clarity and added my
comments in brackets:

···

---------

"It is the unique feature of a box sizer, that it can grow in both
directions (height and width) but can distribute its growth in the
main direction (horizontal for a row) *unevenly* among its children."

[This is the first part of what you want--the ability to make *some
but not all* windows grow in the main direction. Here "grow in the
main direction" means horizontally for a horizontal box sizer,
vertically for a vertical box sizer.]

"In our example case, the vertical sizer is supposed to propagate all
its height changes to only the text area, not to the button area. This
is determined by the *proportion parameter* when adding a window (or
another sizer) to a sizer. It is interpreted as a weight factor, i.e.
*** it can be zero, indicating that the window may not be resized at
all *** "

[There's what you need. 0 proportion parameter means no resizing in
the main direction...that is, horizontally for a horizontal box sizer,
vertically for a vertical one]

", or above zero. If several windows have a value above zero, the
value is interpreted relative to the sum of all weight factors of the
sizer, so when adding two windows with a value of 1, they will both
get resized equally much and each half as much as the sizer owning
them."

[e.g. if I wanted a big text box to take up 2/3 of the available
size,and a panel the remaining third, I'd give the big text box a
proportion parameter of 2 and the panel a proportion parameter of 1.
The sum of 2 + 1 = 3, and so the big text box got 2 out of 3 (2/3) and
the panel just got 1 out of 3 (1/3). As the whole window is resized,
these two components will maintain that proportionality.]

[now on to the part about wx.EXPAND...]

"Then what do we do when a column sizer changes its width?"

[now they are addressing the "non-main" direction. I.e. the vertical
for a horizontal
boxsizer, etc. It's confusing that they are referring to them as
"column sizer" or "row sizer", I agree.]

"This behaviour is controlled by *flags* (the second parameter of the
Add() function): Zero or no flag indicates that the window will
preserve it is original size,"

[note: in that *non-main* direction. This is part two of what you needed.]

"wxGROW flag (same as wxEXPAND) forces the window to grow with the sizer,"

[again, in that *non-main* direction]

-----------

My understanding is that wx will look more native in
non-Linux platforms.

That's right. It should look native.

Lastly, it is good to note that often if you make changes to sizers
you often have to call Layout() on the panel that contains the objects
to be sized. One good way to see if you need to do that is to run
your app, then manually expand the frame by dragging a corner, and if
things suddenly resize, you know you'll need to use Layout after all
the sizing rules are set up.

Che

Cody Precord wrote:

See attached augmented sample.

AttributeError: 'BoxSizer' object has no attribute 'AddStretchSpacer'
AttributeError: 'MainWindow' object has no attribute 'SetInitialSize'

:frowning:

But no matter, I can still say that the program is much better. The text box stretches, and if I just set a reasonable window size the window looks fairly good.

I went through all the changes in your version. I can see that you changed all the sizer settings (wx.EXPAND, etc) and that's what makes the difference. So I'll have to go slowly through the documentation and your example to figure out how your version does what it does.

There are a couple of other changes that I didn't understand:

* textctrl.SetSizeHints(200, -1)
* The wxPanel.

These changes don't seem to affect the layout (maybe I'm just not noticing something). What does a wxPanel do? What does SetSizeHints accomplish if the widget is going to stretch anyways?

Thanks for the help! The window does look correct now. My next step is to learn enough to understand why the window does what it does.

Cheers,
Daniel.

Hi,

Cody Precord wrote:

See attached augmented sample.

AttributeError: 'BoxSizer' object has no attribute 'AddStretchSpacer'
AttributeError: 'MainWindow' object has no attribute 'SetInitialSize'

:frowning:

You must be using wxPython 2.6? If you don't have some reason that you
must use 2.6 I would highly suggest upgrading to wxPython 2.8.

There are a couple of other changes that I didn't understand:

* textctrl.SetSizeHints(200, -1)

You would have seen the affects of this if the SetInitialSize call was
available on your installed version of wxPython. Basically it acts as
a hint to the layout as to what the 'best' minimum size for that
control is. The 200 is the minimum width and -1 means that we don't
care about the minimum vertical height and just want the default.

* The wxPanel.

A Panel is just a container window. You should use it as a container
for controls. Don't put buttons, etc.. directly as children of your
toplevel window.

i.e)

Frame (top level window)
  - Panel (child of Frame)
     - Button (child of Panel)
     - TextCtrl

The layout hierarchy is the same as this, put the panels children into
a sizer that belongs to the Panel, then put the panel into a sizer
that belongs to the frame.

Cody

···

On Wed, Jan 13, 2010 at 12:41 AM, Daniel Carrera <dcarrera@gmail.com> wrote:

Cody Precord wrote:

You must be using wxPython 2.6? If you don't have some reason that you
must use 2.6 I would highly suggest upgrading to wxPython 2.8.

Ok. I was just using whatever came with Ubuntu Karmic. Do I need to upgrade Python too? I have Python 2.6.4.

* textctrl.SetSizeHints(200, -1)

You would have seen the affects of this if the SetInitialSize call was
available on your installed version of wxPython. Basically it acts as
a hint to the layout as to what the 'best' minimum size for that
control is. The 200 is the minimum width and -1 means that we don't
care about the minimum vertical height and just want the default.

Ah. Thanks.

* The wxPanel.

A Panel is just a container window. You should use it as a container
for controls. Don't put buttons, etc.. directly as children of your
toplevel window.

Yeah, but I wasn't doing that (was I?). I had all the controls inside a horizontal box, which I then put on the toplevel window. Was that wrong?

More on that:

The layout hierarchy is the same as this, put the panels children into
a sizer that belongs to the Panel, then put the panel into a sizer
that belongs to the frame.

Yeah, I was just noticing that you did that. You put the panel into a sizer. That's not the only thing you did. I had a horizontal sizer (toHBox). You put that inside a vertical sizer (topVBox), you put that in the panel, and then put the panel in another vertical sizer, and *then* you put it on the window.

What is the purpose of the two extra v-sizers and the panel? What do they accomplish that a simple h-sizer doesn't?

Thanks for the help.

Cheers,
Daniel.

Hi all,

Is there a way to make a button less wide? I have this:

mySizer.Add(wx.Button(panel, ID_CLEAR, "Clear"),0,wx.ALL,5)

The resulting button is a fair bit wider than the word "Clear". It's not too bad, but I would be happier if I could make it a bit less wide.

Thanks.

Cheers,
Daniel.

Hi,

Cody Precord wrote:

You must be using wxPython 2.6? If you don't have some reason that you
must use 2.6 I would highly suggest upgrading to wxPython 2.8.

Ok. I was just using whatever came with Ubuntu Karmic. Do I need to upgrade
Python too? I have Python 2.6.4.

No

* The wxPanel.

A Panel is just a container window. You should use it as a container
for controls. Don't put buttons, etc.. directly as children of your
toplevel window.

Yeah, but I wasn't doing that (was I?). I had all the controls inside a
horizontal box, which I then put on the toplevel window. Was that wrong?

On linux you won't notice much of a difference but on other platforms
(i.e windows) the window will look wrong without the panel in there.

What is the purpose of the two extra v-sizers and the panel? What do they
accomplish that a simple h-sizer doesn't?

I only added one to the panel. I added it because you said you wanted
the controls to be centered vertically as the window was enlarged.

The other one was the sizer for the Frame that contains the Panel.

Cody

···

On Wed, Jan 13, 2010 at 7:47 AM, Daniel Carrera <dcarrera@gmail.com> wrote:

Hi,

···

On Wed, Jan 13, 2010 at 7:58 AM, Daniel Carrera <dcarrera@gmail.com> wrote:

Hi all,

Is there a way to make a button less wide? I have this:

mySizer.Add(wx.Button(panel, ID_CLEAR, "Clear"),0,wx.ALL,5)

The resulting button is a fair bit wider than the word "Clear". It's not too
bad, but I would be happier if I could make it a bit less wide.

See the style flags for wx.Button. In particular wx.BU_EXACTFIT.

http://docs.wxwidgets.org/2.8.10/wx_wxbutton.html#wxbutton

Cody

Cody Precord wrote:

On linux you won't notice much of a difference but on other platforms
(i.e windows) the window will look wrong without the panel in there.

Ok.

What is the purpose of the two extra v-sizers and the panel? What do they
accomplish that a simple h-sizer doesn't?

I only added one to the panel. I added it because you said you wanted
the controls to be centered vertically as the window was enlarged.

The other one was the sizer for the Frame that contains the Panel.

Ok. So you can't put a panel directly below a frame?

Daniel.

Hi,

···

On Wed, Jan 13, 2010 at 8:18 AM, Daniel Carrera <dcarrera@gmail.com> wrote:

Ok. So you can't put a panel directly below a frame?

The panel is a child of the Frame object.

As far as layout goes, Frames will actually handle the sizing
automatically if they only have one child (i.e the Panel), but however
if you start writing Dialogs, they do not automatically handle the
sizing so I think it is good habit to explicitly do it.

Cody

Cody Precord wrote:

See the style flags for wx.Button. In particular wx.BU_EXACTFIT.

http://docs.wxwidgets.org/2.8.10/wx_wxbutton.html#wxbutton

Thanks! In the end, I chose the default (my wife likes it better) but it's nice to learn what the options are.

Cheers,
Daniel.

Also, if you want to be able to traverse the widgets with the TAB key then you'll need the panel as that is where that functionality is implemented. Although some native widgets on some platforms will assist with tabbing from themselves to a sibling, so it sometimes will partially work without a panel, but to fully work everywhere you definitely need to use a panel or other container that is tab-traversal enabled.

···

On 1/13/10 6:04 AM, Cody Precord wrote:

* The wxPanel.

A Panel is just a container window. You should use it as a container
for controls. Don't put buttons, etc.. directly as children of your
toplevel window.

Yeah, but I wasn't doing that (was I?). I had all the controls inside a
horizontal box, which I then put on the toplevel window. Was that wrong?

On linux you won't notice much of a difference but on other platforms
(i.e windows) the window will look wrong without the panel in there.

--
Robin Dunn
Software Craftsman