当其容器面板或框架变小,wxListBox停止使用水平滚动条并扩展占用过多空间
SSCCE 在底部
我的布局有两个 wx.ListBox
,并排放在一个 wx.FlexGridSizer
中:
我的实际布局更复杂,所以用了 FGS,但这个小例子依然能展示出问题。
如上所示,我成功地使用了 style = wx.LB_HSCROLL
,让每个列表框在内容超出 wx.Frame
的时候显示水平滚动条。
然而,当我把窗口缩得越来越小时,最终会达到一个临界点,第一个列表框决定不再使用滚动条,而是扩展到它的最大尺寸,把第二个列表框推到右边:
列表框失控的那个点取决于字符串的长度。如果我在第一个框中放入一个足够长的字符串,那么上述过程就会反转:布局一开始就错了,我必须把窗口的大小调大到临界点,然后列表框突然开始使用滚动条,变得小很多,窗口就会像应该的那样被分成两半。
我不确定这是不是 wxWidgets/wxPython 的一个bug,还是我做错了什么,但无论如何这都让我很沮丧。以下是我能想到的最简单的代码,能展示这个问题:
import wx
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent = None, size = (640, 480))
self.list1 = wx.ListBox(self, style = wx.LB_HSCROLL)
self.list2 = wx.ListBox(self, style = wx.LB_HSCROLL)
self.list1.Append('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
self.list2.Append('bbbbbbbbbbb')
self.fgs = wx.FlexGridSizer(1, 2)
self.fgs.AddMany([(self.list1, 1, wx.EXPAND), (self.list2, 1, wx.EXPAND)])
self.fgs.AddGrowableRow(0, 1)
self.fgs.AddGrowableCol(0, 1)
self.fgs.AddGrowableCol(1, 1)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Sizer = fgs
self.Layout()
self.Show()
def Exit(self, event):
self.Close(True)
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
编辑:这是我用 Python 实现 ravenspoint 代码的版本(上面的代码稍微改动了一下以支持这个):
def OnSize(self, event):
if not self.list1 or not self.list2;
return
clientRect = self.GetClientRect()
min = wx.Size(clientRect.width / 2, clientRect.height)
self.list1.MinSize = min
self.list2.MinSize = min
2 个回答
1
因为我也遇到过这个问题,所以我把这个分享出来,方便以后参考。至少在使用wxPython的时候,你必须指定一个最小大小,否则它会自动选择一个最佳大小(至少对于列表框来说),这样可能会导致布局管理器把一些控件挤到当前窗口的外面。因此,为了让上面的代码正常工作,需要添加的代码是:
self.list1.SetMinSize((10,10));
self.list2.SetMinSize((10,10));
完整的解决方案是:
import wx
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent = None, size = (640, 480))
self.list1 = wx.ListBox(self, style = wx.LB_HSCROLL)
self.list2 = wx.ListBox(self, style = wx.LB_HSCROLL)
self.list1.Append('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
self.list2.Append('bbbbbbbbbbb')
self.fgs = wx.FlexGridSizer(1, 2)
self.fgs.AddMany([(self.list1, 1, wx.EXPAND), (self.list2, 1, wx.EXPAND)])
self.fgs.AddGrowableRow(0, 1)
self.fgs.AddGrowableCol(0, 1)
self.fgs.AddGrowableCol(1, 1)
# Don't forget these two lines to allow for correct
# expansion/contraction of the sizer!
self.list1.SetMinSize((10,10));
self.list2.SetMinSize((10,10));
self.Sizer = self.fgs
self.Layout()
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
1
你可能需要自己处理窗口大小改变的事件。在C++中,处理这个事件的代码大概是这样的:
void MyFrame::OnSize(wxSizeEvent& )
{
if( ! ( list1 && list2 ) )
return;
wxRect frame_client = GetClientRect();
wxSize min(frame_client.width/2,frame_client.height );
list1->SetMinSize(min);
list2->SetMinSize(min);
fgs->Layout();
}