当其包含的面板或框架变得太小时,wxListBox 停止使用其水平滚动条并扩展以占用太多空间

发布于 2024-12-26 05:10:58 字数 1950 浏览 0 评论 0原文

SSCCE 在底部

我的布局有两个 wx.ListBoxes,并排在 wx.FlexGridSizer 中:

到目前为止还好

我的真实布局更为复杂,因此FGS,但这个小例子仍然暴露了这个问题。

正如您在上面所看到的,当列表框的某个元素太大而无法容纳在 wx.LB_HSCROLL 中时,我已成功使用 style = wx.LB_HSCROLL 使每个列表框使用水平滚动条。框架。

然而,当我将窗口大小调整得越来越小时,最终达到了某个临界点,第一个列表框决定不再使用其滚动条,而是扩展到其完整大小,将第二个框推到右侧:

< img src="https://i.sstatic.net/tUgcg.png" alt="窗口太小了!">

列表变得疯狂的点取决于字符串的长度。如果我在第一个框中放置足够长的字符串,那么上述过程就会相反:布局一开始就是错误的,我必须将窗口大小向上调整到临界点,突然间列表框开始使用其滚动条,变得小很多,并且窗口按照应有的方式从中间分开。

我不确定这是否是 wxWidgets/wxPython 中的错误,或者我是否做错了什么,但无论哪种方式都令人沮丧。这是我能想到的显示问题的最简单的代码:

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

SSCCE is at the bottom

My layout has two wx.ListBoxes, side-by side in a wx.FlexGridSizer:

OK so far

My real layout is more complex, thus the FGS, but this small example still exhibits the problem.

As you can see above, I have successfully used style = wx.LB_HSCROLL to make each listbox use a horizontal scroll bar when one of its elements would make it too large to fit in the wx.Frame.

However, as I resize the window smaller and smaller, eventually some critical point is reached, the first listbox decides it doesn't want to use its scrollbar anymore, and instead expands to its full size, pushing the second box to the right:

Window gets too small!

The point at which the list goes crazy depends on how long the string is. If I put a long enough string in the first box, then the above process is reversed: the layout starts off wrong and I have to resize the window up to the critical point, where all of a sudden the listbox starts using its scrollbar, gets a lot smaller, and the window becomes split down the middle as it should be.

I'm not sure if this is a bug in wxWidgets/wxPython or if I'm doing something wrong, but it's frustrating either way. Here is the simplest code I can come up with that shows the problem:

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

EDIT: Here is my implementation of ravenspoint's code in python (code above was changed slightly to support this):

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

贱人配狗天长地久 2025-01-02 05:10:58

您可能需要自己处理调整大小事件。在 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();
}

You may have to look after handling the resize event yourself. In C++ the handler would look something like this:

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();
}
ぇ气 2025-01-02 05:10:58

由于我也遇到了这个问题,所以我将其发布以供将来参考。至少对于 wxPython,您必须指定最小大小,否则它将使用最佳大小(至少对于列表框),并且 sizer 可能会将小部件推到当前窗口框架之外。因此,为使上述代码按预期工作而添加的代码是:

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

Since I ran into this problem as well, I'll post this for future reference. At least with wxPython, you must specify a min size or it will use the best size (at least for list boxes) and the sizer could possibly shove widgets outside of the current window frame. Thus, the added code to get the above code working as desired is:

    self.list1.SetMinSize((10,10));
    self.list2.SetMinSize((10,10));

The total working answer is:

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文