wxPython: может ли wx.PyControl содержать wx.Sizer? - PullRequest
2 голосов
/ 17 июля 2010

Может ли wx.PyControl содержать wx.Sizer?

Обратите внимание, что на то, что я в конечном итоге пытаюсь сделать здесь (счетчик с плавающими значениями), уже дан ответ в другом вопросе.Меня особенно интересует макетирование виджетов в wx.PyControl, навык, который может оказаться полезным, если я столкнусь с необходимостью создавать свои собственные виджеты.Я уже прочитал CreateCustomControls , но в подклассе wx.PyControl он не использовал sizer.

Используя мой код ниже, мой CustomWidget просто не выглядит правильным.Я еще не делаю DoGetBestSize, потому что я думаю, что это относится к wx.Sizer действующему на виджету.Я на самом деле wx.Sizer делаю свое дело внутри a CustomWidget.

Вот мой код (без привязки событий между подвиджетами):
РЕДАКТИРОВАТЬ: Вот мой исправленный код класса, благодаря Стивен Спроат :

import wx

class CustomWidget(wx.PyControl):
  def __init__(self, parent):
    wx.PyControl.__init__(self, parent=parent, style=wx.NO_BORDER) # Style added.
    text = wx.TextCtrl(parent=self)
    spin = wx.SpinButton(parent=self, style=wx.SP_VERTICAL)
    sizer = wx.GridBagSizer()
    self.layout(text, spin, sizer)
    self.OnInit(text, sizer)

  def OnInit(self, text, sizer):
    text.SetValue(u"0.000")

  def layout(self, text, spin, sizer):
    self.SetSizer(sizer)
    sizer.Add(text, pos=(0, 0), flag=wx.ALIGN_CENTER)
    sizer.Add(spin, pos=(0, 1), flag=wx.ALIGN_CENTER)
    self.Fit()
    self.Layout() # This is what I lacked. I needed to call .Layout()
    self.CenterOnParent()

Ответы [ 2 ]

3 голосов
/ 17 июля 2010

Да, это возможно. Вам просто нужно вызвать Layout (), чтобы сказать классификатору пересчитать / разметить его дочерние элементы.

import wx

class Frame(wx.Frame):
  def __init__(self):
    wx.Frame.__init__(self, None)
    blah  = CustomWidget(self)
    self.Show(True)

class CustomWidget(wx.PyControl):
  def __init__(self, parent):
    wx.PyControl.__init__(self, parent=parent)
    text = wx.TextCtrl(parent=self)
    spin = wx.SpinButton(parent=self, style=wx.SP_VERTICAL)
    sizer = wx.GridBagSizer()
    self.layout(text, spin, sizer)
    self.OnInit(text, sizer)

  def OnInit(self, text, sizer):
    text.SetValue(u"0.000")

  def layout(self, text, spin, sizer):
    self.SetSizer(sizer)
    sizer.Add(text, pos=(0, 0), flag=wx.ALIGN_CENTER)
    sizer.Add(spin, pos=(0, 1), flag=wx.ALIGN_CENTER)
    self.Fit()
    self.Layout()
    self.CenterOnParent()

app = wx.App()
f = Frame()
app.MainLoop()

Кстати, было бы неплохо в будущем, если бы вы могли прикрепить исполняемый образец, как указано выше:)

1 голос
/ 19 июля 2010

Поскольку классы, производные от wxControl, обычно не используются для хранения других виджетов, код автоматического макета отсутствует и поэтому он не будет вызывать Layout (), когда он получает событие EVT_SIZE. Вы можете легко добавить эту способность в свой класс, используя Bind (), обрабатывая EVT_SIZE и вызывая self.Layout () оттуда. Затем он будет действовать так же, как и панель, когда он получает событие size, имеет дочерние элементы и sizer.

...