0

我正在尝试制作这样的 GUI:

我的预期布局图片

大方块是 wxGrid,小方块是 wxButton,它们都表现良好。左边的图是一个 wxSlider,在滑块的每一端下方都有文本标签“slow”和“fast”。

所以我布置了一堆 BoxSizer,如下所示:

BoxSizer 的层次结构

从外到内:

  • 蓝色是垂直的,包含一个 wxGrid 和绿色的 BoxSizer
  • 绿色是水平的,包含橙色 BoxSizer 和两个按钮
  • 橙色是垂直的,包含一个 wxSlider 和紫色的 BoxSizer
  • Purple是水平的,包含两个StaticText,分别是“slow”和“fast”

但我能得到的最接近渲染的是这个。特别注意滑块是多么的小,而慢速和快速标签(旨在标记滑块的末端!)是一团糟。 我糟糕的结果

我搞砸了对齐和扩展,我读过一堆其他人抱怨 BoxSliders 的帖子,但我一无所获。当我读到有关 wx.ST_NO_AUTORESIZE 的信息时,我以为我肯定拥有它,但这并没有做任何事情。我什至用 wxGlade 重建了我的窗口,得到了同样的结果,尤其是在最左边的静态文本。

我没有做的一件事是以像素为单位指定任何东西的大小。似乎任何布局都不需要这样做,因为谁知道我将在什么尺寸的屏幕上运行或合理的像素数是多少。如果我已经正确理解了 sizer 中的比例,我就不必以像素为单位指定大小。

但是我没有想法,我什至没有找到一个很好的例子,只是类似的挫败感。如何让我的滑块占据橙色 boxsizer 的整个宽度,以及如何让慢速和快速文本标记滑块的末端?

我正在运行的内容,剥离到布局要素(并且存在滑块和标签问题):

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()
4

2 回答 2

3

有一个“内置”选项用于显示滑块的最小和最大标签:wxSL_MIN_MAX_LABELS在创建它时使用(除非您使用的 wxWidgets 早于 2.9.1)。

否则,对于您特定的 sizer 布局(如果您在使用之前创建每个 sizer 可能会更容易查看):

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())
于 2021-11-08T08:23:26.270 回答
0

正如@VZ 向我指出的那样,Alignboxsizer 中的旧版本在其方向上从未起作用,但现在在 wxWidgets 的较新迭代中引发错误。
现在,old实现相同结果的方法是在 中插入dummy条目sizer并要求扩展它们。

有关new方式,请参阅@catalin 的答案。

您的代码的一些更改是装饰性的,以帮助我理解什么是什么,通过显式而不是隐式的小部件默认值。

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(wx.HORIZONTAL)
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(wx.HORIZONTAL)
label_slow = wx.StaticText(frame, label="Slow")
label_fast = wx.StaticText(frame, label="Fast")
purple_sizer.Add(label_slow, 0, 0, 0)
purple_sizer.Add((-1,-1), 1, wx.EXPAND, 0)
purple_sizer.Add(label_fast, 0, 0, 0)

orange_sizer = wx.BoxSizer(wx.VERTICAL)
orange_sizer.Add(slider, 0, wx.EXPAND)
orange_sizer.Add(purple_sizer, 0, wx.EXPAND)

green_sizer.Add(orange_sizer, 2, 0, 0)
green_sizer.Add(button1, 1, wx.EXPAND)
green_sizer.Add(button2, 1, wx.EXPAND)

frame.SetSizerAndFit(blue_sizer)
frame.Show()

app.MainLoop()

在此处输入图像描述

注意:
这是虚拟条目: purple_sizer.Add((-1,-1), 1, wx.EXPAND, 0)

于 2021-11-08T08:24:28.907 回答