【问题标题】:wxPython: "Super" wx.SpinCtrl with float values, layout inside sizerwxPython:具有浮点值的“超级” wx.SpinCtrl,在 sizer 内布局
【发布时间】:2011-03-16 17:40:52
【问题描述】:

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

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

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

现在,我刚刚撞到了一堵砖墙。我的组合课程不适用于sizer。在 .Add() 将组合类添加到 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)

【问题讨论】:

    标签: python wxpython spinner sizer


    【解决方案1】:

    正如 Kit 的 cmets 中提到的,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()
    

    【讨论】:

      【解决方案2】:

      如果你希望你的控制是,你需要重写 DoGetBestSize() 由sizer正确管理。看看CreatingCustomControls

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

      回应您的 cmets:

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

      【讨论】:

      • 好的,我去看看wx.lib.agw.FloatSpin。关于您给我的另一个链接(CreatingCustomControls),它需要直接绘制位图,我目前不愿意这样做。 wxPython 中是否有一个程序可以使 sizer 将两个小部件视为一个小部件?在 MS Word 中绘制多个对象时,应该类似于 group 功能。
      • FloatSpin 看起来很有希望:) 但是这个wx.PyControl 和一个包含我的wx.Sizerwx.TextCtrlwx.SpinButton 真的很有趣。我遇到了.SetSizer(sizer)wx.PyControl 的问题,但这将是另一个问题。感谢您抽出宝贵时间,拉尔夫!
      猜你喜欢
      • 2013-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-26
      • 2012-01-24
      • 2021-06-09
      • 1970-01-01
      • 2020-03-10
      相关资源
      最近更新 更多