wxPython: “Супер” wx. SpinCtrl со значениями плавающими, расположением в классификаторе

wx.SpinCtrl ограничен вращением через целые числа и не плаваниями. Поэтому я создаю a wx.TextCtrl + wx.SpinButton комбинированный класс, который позволяет мне вращаться через плавания. Я могу измерить и расположение они оба программно так, чтобы комбинация посмотрела точно то же как дежурное блюдо wx.SpinCtrl.

Я разделяю эту комбинацию на подклассы от wx.TextCtrl потому что я хочу, чтобы его родительская панель поймала wx.EVT_TEXT события. Я ценил бы, если можно изменить к лучшему этот мой аргумент.

wx.EVT_SPIN_UP и wx.EVT_SPIN_DOWN события от wx.SpinButton и внутренние реализации и родительский кадр, не заботится об этих событиях.

Теперь, я просто врезался в кирпичную стену. Мой комбинированный класс не работает хорошо с классификаторами. После .Add()луг комбинированный класс к a wx.GridBagSizer, только wx.TextCtrl размечается в wx.GridBagSizer. wx.SpinButton оставлен самостоятельно отдельно. wx.EVT_SPIN* привязка работает очень хорошо, все же.

Моей проблемой является расположение. Как я должен записать класс, если я хочу wx.GridBagSizer рассматривать его как один виджет?

Вот мой комбинированный код класса:

class SpinnerSuper(wx.TextCtrl):
  def __init__(self, parent, max):
    wx.TextCtrl.__init__(self, parent=parent, size=(48, -1))
    spin = wx.SpinButton(parent=parent, style=wx.SP_VERTICAL, size=(-1, 21))
    self.OnInit()
    self.layout(spin)
    self.internalBindings(spin)
    self.SizerFlag = wx.ALIGN_CENTER

    self.min = 0
    self.max = max

  def OnInit(self):
    self.SetValue(u"0.000")

  def layout(self, spin):
    pos = self.GetPosition()
    size = self.GetSize()
    RightEdge = pos[0] + size[0]
    TopEdge = pos[1] - (spin.GetSize()[1]/2 - size[1]/2)
    spin.SetPosition((RightEdge, TopEdge))

  def internalBindings(self, spin):
    spin.Bind(wx.EVT_SPIN_UP, self.handlerSpinUp(self), spin)
    spin.Bind(wx.EVT_SPIN_DOWN, self.handlerSpinDown(self), spin)

  def handlerSpinUp(CallerObject, *args):
    def handler(CallerObject, *data):
        text = data[0]
        prev = text.GetValue()
        next = float(prev) + 0.008
        text.SetValue("{0:0.3f}".format(next))
    return lambda event: handler(CallerObject, *args)

  def handlerSpinDown(CallerObject, *args):
    def handler(CallerObject, *data):
        text = data[0]
        prev = text.GetValue()
        next = float(prev) - 0.008
        text.SetValue("{0:0.3f}".format(next))
    return lambda event: handler(CallerObject, *args)
5
задан Kit 16 July 2010 в 01:41
поделиться

1 ответ

Вам необходимо переопределить DoGetBestSize(), если вы хотите, чтобы ваш элемент управления был правильно управлялся сайзерами. Посмотрите CreatingCustomControls.

Вы также можете взглянуть на FloatSpin, который поставляется с wxPython (в wx.lib.agw) начиная с версии 2.8.9.2 и выше.

В ответ на ваши комментарии:

  • Реализация DoGetBestSize() не требует рисования растровых изображений напрямую. Вам просто нужно найти способ, как определить оптимальный размер вашего нового виджета. Обычно вы просто используете размеры двух виджетов, из которых он состоит (текст + спиннер).
  • Чтобы позволить сайзерам рассматривать два виджета как один, вы можете поместить их в другой сайзер.
  • Рекомендуемый способ реализации пользовательского виджета с помощью wxPython - создать новый виджет на основе wx.PyControl, добавить к нему сайзер и добавить два виджета, которые вы хотите объединить, в этот сайзер.
4
ответ дан 14 December 2019 в 18:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: