wxPython:“;超级";wx.SpinCtrl,带浮点值,在尺寸标注器内布局

wxPython:“;超级";wx.SpinCtrl,带浮点值,在尺寸标注器内布局,python,wxpython,spinner,sizer,Python,Wxpython,Spinner,Sizer,wx.SpinCtrl仅限于在整数之间旋转,而不是浮动。因此,我正在构建一个wx.TextCtrl+wx.SpinButtoncombo类,它使我能够在浮点数之间旋转。我能够以编程方式调整它们的大小和布局,使组合看起来与普通的wx.SpinCtrl完全相同 我正在从wx.TextCtrl子类化这个组合,因为我希望它的父面板捕获wx.EVT\u TEXT事件。如果你能改进我的论点,我将不胜感激 wx.SpinButton中的wx.EVT\u自旋向上和wx.EVT\u自旋向下事件都是内部实现,父帧不

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

我正在从
wx.TextCtrl
子类化这个组合,因为我希望它的父面板捕获
wx.EVT\u TEXT
事件。如果你能改进我的论点,我将不胜感激

wx.SpinButton
中的
wx.EVT\u自旋向上
wx.EVT\u自旋向下
事件都是内部实现,父帧不关心这些事件

现在,我撞到了一堵砖墙。我的combo类与Sizer不兼容。在
.Add()
将combo类添加到
wx.GridBagSizer
之后,只有
wx.TextCtrl
wx.GridBagSizer
中布局。
wx.SpinButton
是独立的。不过,
wx.EVT\u 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)

如果希望控件处于活动状态,则需要重写DoGetBestSize() 由Sizer正确管理。看一看

你也可以看看wxPython的飞船 (在wx.lib.agw中)从版本2.8.9.2向上

针对你的评论:

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

正如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()

好的,我来看看
wx.lib.agw.FloatSpin
。关于你给我的另一个链接(CreatingCustomControls),它需要直接绘制位图,我现在不愿意这样做。wxPython中是否有一个过程可以使一个大小调整器将两个小部件视为一个?在MS Word中绘制许多对象时,它应该类似于group函数。
FloatSpin
看起来很有希望:)但是这个
wx.PyControl
带有
wx.Sizer
wx.TextCtrl
wx.SpinButton
确实很有趣。我在
.SetSizer(sizer)
调用
wx.PyControl
时遇到问题,但那将是另一个问题。谢谢你的时间,拉尔夫!