wxPython:具有浮点值的"超级"wx.SpinCtrl,sizer内部的布局

Kit*_*Kit 5 python wxpython spinner sizer

wx.SpinCtrl仅限于整数旋转,而不是浮动.因此,我正在构建一个wx.TextCtrl+ wx.SpinButtoncombo类,这使我能够跨越浮点数.我能够以编程方式对它们进行大小和布局,以使组合看起来与普通组件完全相同wx.SpinCtrl.

我从这里继承了这个组合,wx.TextCtrl因为我希望它的父面板能够捕获wx.EVT_TEXT事件.如果你能改进我的这个论点,我将不胜感激.

wx.EVT_SPIN_UPwx.EVT_SPIN_DOWN从事件wx.SpinButton都是内实现和父框架并不关心这些事件.

现在,我刚碰到一堵砖墙.我的组合类与sizer不兼容.在.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)
Run Code Online (Sandbox Code Playgroud)

Ral*_*lph 4

如果您希望您的控件能够由 sizer 正确管理,您需要重写 DoGetBestSize()。看一下创建自定义控件

您还可以查看2.8.9.2 及以上版本的 wxPython(在 wx.lib.agw 中)附带的FloatSpin 。

针对您的评论:

  • 实现DoGetBestSize()不需要直接绘制位图。您只需要找到一种方法,如何确定新小部件的最佳尺寸。通常,您只需使用它所组成的两个小部件(文本+微调器)的大小作为基础。
  • 要让 sizer 将两个小部件视为一个小部件,您可以将它们放置在另一个 sizer 中。
  • 使用 wxPython 实现自定义小部件的推荐方法是从 wx.PyControl 派生新小部件,向其添加一个 sizer,然后将要组合的两个小部件添加到该 sizer。