5

wx.SpinCtrl浮動小数点ではなく、整数間での回転に制限されています。したがって、フロート間でスピンできるwx.TextCtrl+wx.SpinButtonコンボクラスを構築しています。コンボが通常とまったく同じに見えるように、プログラムで両方のサイズとレイアウトを設定できますwx.SpinCtrl

wx.TextCtrl親パネルにイベントをキャッチさせたいので、このコンボをからサブクラス化しwx.EVT_TEXTます。私のこの議論を改善していただければ幸いです。

からのイベントwx.EVT_SPIN_UPwx.EVT_SPIN_DOWNイベントwx.SpinButtonは両方とも内部実装であり、親フレームはこれらのイベントを考慮しません。

今、私はレンガの壁にぶつかった。私のコンボクラスはサイザーではうまく機能しません。.Add()コンボクラスをにした後wx.GridBagSizer、はだけが。wx.TextCtrl内に配置されますwx.GridBagSizer。はwx.SpinButtonそれ自体で残されます。ただし、wx.EVT_SPIN*バインディングは非常にうまく機能します。

私の問題はレイアウトです。wx.GridBagSizerクラスを1つのウィジェットとして扱いたい場合、どのようにクラスを作成すればよいですか?

これが私のコンボクラスコードです:

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

コントロールをサイザーで正しく管理する場合は、DoGetBestSize()をオーバーライドする必要があります。CreationCustomControlsをご覧ください。

バージョン2.8.9.2以降のwxPython(wx.lib.agw内)に同梱されているFloatSpinもご覧ください。

あなたのコメントに応えて:

  • DoGetBestSize()を実装するために、ビットマップを直接描画する必要はありません。新しいウィジェットの最適なサイズを決定する方法を見つける必要があります。通常は、構成されている2つのウィジェット(テキスト+スピナー)のサイズを基本として使用します。
  • サイザーが2つのウィジェットを1つとして扱うようにするには、それらを別のサイザーに配置します。
  • wxPythonでカスタムウィジェットを実装するための推奨される方法は、wx.PyControlから新しいウィジェットを派生させ、それにサイザーを追加し、結合する2つのウィジェットをそのサイザーに追加することです。
于 2010-07-16T02:00:31.200 に答える
1

キットのコメントで述べ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 に答える