I'm trying to make a GUI like so:
The big square is a wxGrid, the small ones are wxButtons, and they all act fine. The drawing at left is intended to be a wxSlider, with text labels "slow" and "fast" beneath each end of the slider.
So I lay out a bunch of BoxSizers, like this:
From outside in:
But the closest I can get it to render is this. Notice especially how the slider is tiny, and the slow and fast labels (intended to mark the ends of the slider!) are a mess.
I've messed with alignments and expands, I've read a bunch of posts from other people complaining about BoxSliders, and I've gotten nowhere. I thought for sure I had it when I read about wx.ST_NO_AUTORESIZE, but that didn't do anything. I even rebuilt my window with wxGlade, and got the same thing, especially with the static text laid out far left.
The one thing I haven't done is specified the size of anything in pixels. It doesn't seem like any layout should require that, because who knows what size screen I'll be running on or what a reasonable number of pixels is. And if I've understood proportions correctly in sizers, I don't have to specify sizes in pixels.
But I'm out of ideas, and I haven't even found a good example, just similar veins of frustration. How do I make my slider take up the full width of the orange boxsizer, and how do I get the slow and fast text to label the ends of the slider?
What I'm running, stripped to the layout essentials (and it's got the slider and labels problem):
import wx
import wx.grid
app = wx.App()
frame = wx.Frame(None, title="MyUnhappyLayout")
blue_sizer = wx.BoxSizer(wx.VERTICAL)
grid = wx.grid.Grid(frame)
blue_sizer.Add(grid, 6, wx.EXPAND, 8)
green_sizer = wx.BoxSizer()
blue_sizer.Add(green_sizer, 1, wx.EXPAND)
button1 = wx.Button(frame)
button2 = wx.Button(frame)
slider = wx.Slider(frame, name="Speed", value=1, minValue=1, maxValue=100)
purple_sizer = wx.BoxSizer()
label_slow = wx.StaticText(frame, label="Slow")
label_fast = wx.StaticText(frame, label="Fast")
purple_sizer.Add(label_slow, wx.ALIGN_LEFT)
purple_sizer.Add(label_fast, wx.ALIGN_RIGHT)
orange_sizer = wx.BoxSizer(wx.VERTICAL)
green_sizer.Add(orange_sizer, 2)
orange_sizer.Add(slider)
orange_sizer.Add(purple_sizer, wx.EXPAND)
green_sizer.Add(button1, 1, wx.EXPAND)
green_sizer.Add(button2, 1, wx.EXPAND)
frame.SetSizerAndFit(blue_sizer)
frame.Show()
app.MainLoop()
There is a "built-in" option for showing min and max labels for a slider: use wxSL_MIN_MAX_LABELS
when creating it (unless you are using wxWidgets older than 2.9.1).
Otherwise, for your specific sizer layout (it might be easier to review if you create each sizer just before using it):
purple_sizer = wx.BoxSizer()
purple_sizer.Add(label_slow)
purple_sizer.AddStretchSpacer()
purple_sizer.Add(label_fast)
orange_sizer = wx.BoxSizer(wx.VERTICAL)
# when adding to a sizer, the second argument would be proportion;
# use SizerFlags to avoid mistakenly skipping an argument
orange_sizer.Add(slider, wx.SizerFlags().Expand())
orange_sizer.Add(purple_sizer, wx.SizerFlags().Expand())
green_sizer = wx.BoxSizer()
green_sizer.Add(orange_sizer, wx.SizerFlags(1)) # no need for proportion=2, 1 should do
green_sizer.Add(button1) # you probably meant to enlarge the slider, not the buttons
green_sizer.Add(button2)
blue_sizer = wx.BoxSizer(wx.VERTICAL)
blue_sizer.Add(grid, wx.SizerFlags(1).Expand().Border(8)) # no need for proportion=6, 1 should do
blue_sizer.Add(green_sizer, wx.SizerFlags().Expand())