Сайзер ведет себя не так, как планировалось…

Я создаю графический интерфейс с несколькими различными панелями, которые я не хочу видеть в одном и том же классификаторе: хотя они показывают связанные вещи, они должны быть отдельными. У меня есть несколько панелей, каждая из которых имеет свой собственный классификатор, добавляемый в классификатор верхнего уровня. Все идет нормально. Тем не менее, я не могу понять, как получить размеры для фактического размера панелей.

Мне интересно понять, что я не пропустил, а не простая отладка.

Теперь кажется, что поведение может меняться в зависимости от версии и ОС, поэтому вот мое:

  • CentOS 7.
  • Python 3.6.
  • wxPython 4.0.0b1.
  • Чтобы добавить к усложнению, этот код должен в конечном итоге работать и на Windows 10.

Вот что я сейчас получаю:

ПЛОХОЙ

Это то, что я хотел бы случиться:

Хорошо

Хотя нет границ слева и справа, несмотря на то, что добавили один. Я подозреваю, что код сортировщика портит все и поэтому игнорирует границы.

Исходный код, такой как он есть:

import wx.lib.agw.floatspin as FS
import wx


class GUICalibration(wx.Frame):
    """A calibration GUI for raiju…"""

    def __init__(self, parent, id, title):
        super(GUICalibration, self).__init__(parent, id, title)
        panel = wx.Panel(self)
        panel.SetBackgroundColour('#5968c3')
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self._ui(panel), 1, wx.EXPAND | wx.ALL, 3)
        sizer.SetSizeHints(panel)
        panel.SetSizer(sizer)
        self.Centre()
        self.Show(True)

    def _ui(self, parent):
        panel = wx.Panel(parent)
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self._ui_prefix(panel), flag=wx.EXPAND)
        vbox.Add(self._ui_input(panel), wx.EXPAND)
        vbox.AddStretchSpacer()
        vbox.Add(self._ui_suffix(panel), flag=wx.EXPAND)
        vbox.SetSizeHints(parent)
        panel.SetSizer(vbox)
        return panel

    def _ui_prefix(self, parent):
        panel = wx.Panel(parent)
        panel.SetBackgroundColour('steelblue')
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        _label = wx.StaticText(panel, label='')
        _label.SetLabelMarkup("<b><i><big>Calibration</big></i></b>")
        hbox.Add(_label, flag=wx.ALIGN_CENTER | wx.ALL)
        panel.SetSizer(hbox)
        return panel

    def _ui_input(self, parent):
        box = wx.StaticBox(parent, -1, "Calibration input")
        fgs = wx.FlexGridSizer(3, 3, 11, 11)
        flags = wx.EXPAND | wx.ALL

        _spin_count = wx.SpinCtrl(
            box, wx.ID_ANY, '0', min=0, max=1000, size=(128, -1))
        _spin_value = FS.FloatSpin(
            box,
            wx.ID_ANY,
            size=(128, -1),
            value=0.0,
            min_val=-40.0,
            max_val=100.0,  # FIXME
            increment=0.1)
        _spin_value.SetFormat("%f")
        _spin_value.SetDigits(1)
        _add = wx.Button(box, wx.ID_ANY, "Add calibration data")

        fgs.Add(wx.StaticText(box, label='Count'), 0, flags)
        fgs.Add(wx.StaticText(box, label='Value'), 0, flags)
        fgs.AddStretchSpacer()

        fgs.Add(_spin_count, 0, flags)
        fgs.Add(_spin_value, 0, flags)
        fgs.Add(_add, 0, flags)

        fgs.SetSizeHints(box)
        box.SetSizer(fgs)
        return box

    def _ui_suffix(self, parent):
        panel = wx.Panel(parent)
        panel.SetBackgroundColour('steelblue')
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        hbox.Add(
            wx.BoxSizer(wx.VERTICAL), flag=wx.RESERVE_SPACE_EVEN_IF_HIDDEN)
        _quit = wx.Button(panel, wx.ID_ANY, "Quit")
        _quit.SetBackgroundColour('#5968c3')
        self.Bind(wx.EVT_BUTTON, self.OnQuit, _quit)
        hbox.AddStretchSpacer()
        hbox.Add(_quit, flag=wx.ALIGN_CENTER | wx.SHAPED | wx.ALL, border=3)
        hbox.AddStretchSpacer()
        panel.SetSizer(hbox)
        return panel

    def OnQuit(self, e):
        self.Close()


if __name__ == '__main__':
    """This is useful for testing the frame…"""
    app = wx.App()
    GUICalibration(None, -1, title='Calibration')
    app.MainLoop()

1 ответ

Решение

Сносное решение гласит:

class GUICalibration(wx.Frame):

    def __init__(self, parent, id, title):
        self._logger = logging.getLogger(self.__class__.__name__)
        super(GUICalibration, self).__init__(parent, id, title)
        self._ui(self)
        self.Fit()
        self.SetAutoLayout(True)
        self.Centre()
        self.Show()

    def _ui(self, parent):
        panel = wx.Panel(self)
        sizer = wx.FlexGridSizer(1, 5, 5)
        sizer.Add(self._ui_frame(panel), 1, wx.EXPAND | wx.ALL, 3)
        sizer.Add(self._ui_frame(panel), 1, wx.EXPAND | wx.ALL, 3)
        sizer.Add(self._ui_frame(panel), 1, wx.EXPAND | wx.ALL, 3)
        panel.SetSizerAndFit(sizer)
        return panel

    def _ui_frame(self, parent):
        sizer = wx.StaticBoxSizer(wx.VERTICAL, parent, 'test',)
        sizer.Add(wx.Button(parent, -1, 'A very ' + 20 * 'long ' + 'text'), 0, 0, 0)
        sizer.Add(wx.Button(parent, -1, 'Small button'), 0, wx.EXPAND | wx.ALL, 20)
        return sizer

Код префикса и суффикса был опущен, чтобы сделать код короче, но включен в снимок экрана.

Проблемы с этим решением в два раза: во-первых, изменение размера окна не меняет размер ни одного из классификаторов: они остаются с минимально возможным размером, который подходит. Во-вторых, я потерял цвет фона панели верхнего уровня. Зачем? Понятия не имею ни по одному пункту.

сносное решение

Другие вопросы по тегам