расширять wxWrapSizer во вторичном направлении при добавлении новых элементов - PullRequest
1 голос
/ 16 июня 2020

У меня есть панель со списком кнопок. Количество кнопок изменяется во время выполнения (из-за действий пользователя в другом месте). Я использую wxWrapSizer для управления этими кнопками, так как я хочу, чтобы высота этой панели оставалась прежней, и создавал второй столбец кнопок, когда на ней заканчивается вертикальное пространство. Высота управляется родительским измерителем размеров на основе высоты других виджетов. Это почти нормально работает, но второй столбец кнопок не появляется до тех пор, пока размер окна не будет изменен вручную.

Я создал минимальный пример для воспроизведения проблемы:

import wx

start_buttons = 5

class ButtonsPanel(wx.Panel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.SetSizer(wx.WrapSizer(wx.VERTICAL))
        for i in range(start_buttons):
            self.add_button()

    def add_button(self):
        self.GetSizer().Add(wx.Button(self, label='foo'),
                            wx.SizerFlags().Expand())


class MyPanel(wx.Panel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # hardcoded size for sake of example only
        add_button = wx.Button(self, label="add", size=(80, 250))
        add_button.Bind(wx.EVT_BUTTON, self.OnAddButton)

        self.buttons_panel = ButtonsPanel(self)

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(add_button)
        sizer.Add(self.buttons_panel, wx.SizerFlags().Expand())
        self.SetSizer(sizer)

    def OnAddButton(self, evt):
        self.buttons_panel.add_button()
        self.buttons_panel.Layout()


class MyFrame(wx.Frame):
    def __init__(self, *args):
        super().__init__(*args)
        panel = MyPanel(self)


app = wx.App()
frame = MyFrame(None)
frame.Show()

app.MainLoop()

Щелчок по Кнопка «Добавить» добавит новые кнопки «foo», но затем остановится, когда достигнет нижней части кадра. При изменении размера рамки вручную появится второй скрытый столбец.

screenshot of the example running

1 Ответ

1 голос
/ 16 июня 2020

Выполните Layout() калибровку основной панели, а не калибровку панели кнопок.

Поскольку калибровщик панели кнопок «живет» внутри калибровщика основной панели, это тот, который необходимо пересчитать, поскольку он будет пересчитывать его дочерние элементы.

def OnAddButton(self, evt):
    self.buttons_panel.add_button()
    #self.buttons_panel.Layout()
    self.Layout()

Изменить:
для более сложных настроек вам может потребоваться отметить parent или grandparent и обновить его из панели кнопок, т.е.

import wx

start_buttons = 5

class ButtonsPanel(wx.Panel):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.SetSizer(wx.WrapSizer(wx.VERTICAL))
        self.parent = parent
        for i in range(start_buttons):
            self.add_button()

    def add_button(self):
        self.GetSizer().Add(wx.Button(self, label='foo'),
                            wx.SizerFlags().Expand())
        self.parent.Layout()

class MyPanel(wx.Panel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # hardcoded size for sake of example only
        add_button = wx.Button(self, label="add", size=(80, 250))
        add_button.Bind(wx.EVT_BUTTON, self.OnAddButton)

        self.buttons_panel = ButtonsPanel(self)

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(add_button)
        sizer.Add(self.buttons_panel, wx.SizerFlags().Expand())
        self.SetSizer(sizer)

    def OnAddButton(self, evt):
        self.buttons_panel.add_button()
        #self.buttons_panel.Layout()

class MyFrame(wx.Frame):
    def __init__(self, *args):
        super().__init__(*args)
        panel = MyPanel(self)


app = wx.App()
frame = MyFrame(None)
frame.Show()

app.MainLoop()

Если это действительно адски sh, вы можете использовать pubsub, чтобы выстрелить Layout в нужном месте.

...