2010-07-16 41 views
5

wx.SpinCtrl僅限於跨整數旋轉,而不是浮動。因此,我正在構建一個wx.TextCtrl + wx.SpinButton組合類,它使我可以旋轉浮游物。我能夠以編程方式對它們進行大小和佈局,以便組合看起來與普通wx.SpinCtrl完全相同。wxPython:「超級」wx.SpinCtrl浮點值,sizer內的佈局

我從wx.TextCtrl繼承這個組合,因爲我想讓它的父面板捕捉wx.EVT_TEXT事件。如果你能改進我的這個論點,我將不勝感激。

wx.EVT_SPIN_UPwx.EVT_SPIN_DOWN來自wx.SpinButton的事件都是內部實現,並且父框架不關心這些事件。

現在,我只是碰到一堵磚牆。我的組合類不適用於sizer。在組合類別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) 

回答

3

你需要重寫DoGetBestSize()如果你希望你的控制是通過 正確的大小測定器管理。看看CreatingCustomControls

你也可以看看FloatSpin,從版本2.8.9.2開始,wxPython (位於wx.lib.agw)。

在回答您的評論:

  • 實施DoGetBestSize()並不需要直接繪製位圖。你只需要找到一種方法,你如何確定新小部件的最佳尺寸。通常,您只需使用由它構成的兩個小部件(文本+微調器)的大小作爲基礎。
  • 要讓sizer將兩個小工具視爲一個小工具,您可以將它們放在另一個小工具中。
  • 使用wxPython實現自定義窗口小部件的推薦方式是從wx.PyControl派生您的新窗口小部件,向其添加sizer並添加要與該sizer組合的兩個窗口小部件。
+0

好吧,我會看看'wx.lib.agw.FloatSpin'。 關於您給我的其他鏈接(CreatingCustomControls),它需要直接繪製位圖,目前我不願意這樣做。 在wxPython中有一個使sizer能夠將兩個小部件視爲一個的過程嗎?在MS Word中繪製多個對象時,它應該與組功能類似。 – Kit 2010-07-16 04:09:51

+0

'FloatSpin'看起來很有前景:)但是這個'wx.PyControl'與'wx.Sizer'包含我的'wx.TextCtrl'和'wx.SpinButton'真的很有趣。我遇到'SetSizer(sizer)''wx.PyControl'的問題,但那會是另一個問題。謝謝你的時間,拉爾夫! – Kit 2010-07-17 12:51:07

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