5

wx.SpinCtrl仅限于在整数上旋转,而不是浮点数。因此,我正在构建一个wx.TextCtrl+wx.SpinButton组合类,它使我能够在花车上旋转。我能够以编程方式调整它们的大小和布局,使组合看起来与普通的wx.SpinCtrl.

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

wx.EVT_SPIN_UPwx.EVT_SPIN_DOWN事件wx.SpinButton都是内部实现,父框架不关心这些事件。

现在,我刚刚撞到了一堵砖墙。我的组合课程不适用于sizer。.Add()将组合类设置为 a后wx.GridBagSizer,仅wx.TextCtrlwx.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)
4

2 回答 2

4

如果您希望您的控件由 sizer 正确管理,则需要覆盖 DoGetBestSize()。看看CreatingCustomControls

您还可以查看从2.8.9.2版本开始随 wxPython(在 wx.lib.agw 中)一起提供的 FloatSpin。

回应您的评论:

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

正如 Kit 的评论中提到的,FloatSpin现在是要走的路。

它已集成在最新版本中。

下面是一个简单的用法示例:

import wx
from wx.lib.agw.floatspin import FloatSpin

class Example_FloatSpin(wx.Frame):
    def __init__(self, parent, title):
        super(Example_FloatSpin, self).__init__(parent, title=title, size=(480, 250))
        panel = wx.Panel(self)

        vbox = wx.BoxSizer(wx.VERTICAL)
        spin = FloatSpin(panel, value=0.0, min_val=0.0, max_val=8.0, increment=0.5, digits=2, size=(100,-1))
        vbox.Add(spin, proportion=0, flag=wx.CENTER, border=15)
        panel.SetSizer(vbox)

        self.Centre()
        self.Show() 


if __name__ == '__main__':
    app = wx.App()
    Example_FloatSpin(None, title='Check FloatSpin')
    app.MainLoop()
于 2016-12-22T14:01:04.110 回答