Когда содержащая его панель или рамка становится слишком маленькой, wxListBox прекращает использовать горизонтальную полосу прокрутки и расширяется, чтобы занять слишком много места - PullRequest
2 голосов
/ 11 января 2012

SSCCE внизу

У моего макета есть два wx.ListBox рядом друг с другом в wx.FlexGridSizer:

OK so far

Мое реальное расположение более сложное, таким образом, FGS, но этот маленький пример все еще демонстрирует проблему.

Как вы можете видеть выше, я успешно использовал style = wx.LB_HSCROLL, чтобы каждый список использовал горизонтальную полосу прокрутки, когда один из его элементов сделал бы его слишком большим, чтобы поместиться в wx.Frame.

Однако, когда я изменяю размер окна все меньше и меньше, в конечном итоге достигается некоторая критическая точка, первый список решает, что больше не хочет использовать полосу прокрутки, и вместо этого расширяется до своего полного размера, толкая второе поле к право:

Window gets too small!

Точка, в которой список сходит с ума, зависит от длины строки. Если я поместил достаточно длинную строку в первый блок, то вышеописанный процесс будет изменен на обратный: макет начинается неправильно, и мне приходится изменять размер окна до до критической точки, где внезапно появляется список начинает использовать полосу прокрутки, становится намного меньше, и окно разделяется на середину, как и должно быть.

Я не уверен, является ли это ошибкой в ​​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()

РЕДАКТИРОВАТЬ: Вот моя реализация кода ravenspoint в Python (код выше был немного изменен для поддержки этого):

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 голос
/ 25 ноября 2015

Так как я столкнулся с этой проблемой, я опубликую это для дальнейшего использования. По крайней мере, для 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 голос
/ 11 января 2012

Возможно, вам придется самостоятельно следить за обработкой события изменения размера.В 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();
}
...