2012-04-20 36 views
1

私は自分自身(Wx)Pythonを教えていて、立ち往生しています。私は自分のコードの大部分を含んでいる私のTestFrameの中に情報の定期的なセットを持つ子ウィンドウを作成したいと思います。問題は、コード内にウィジェットが1つしか表示されないことです。私は次のことを、私の重要性の順に理解しようとしています。WxPython:子ウィンドウの複数のウィジェット

**このコードはthisページへの拡張であることに注意してください。*

  1. 私は「AddBox」クラスの複数のウィジェットが正しく表示されるようにするにはどうすればよいですか?
  2. ウィンドウのサイズを変更すると、添付されている画面のようにボタンイメージが破損します。どうすればこの問題を解決できますか?
  3. これらの動的に作成されたウィジェットのそれぞれをどのように呼び出し/バインドしますか?
  4. ボーナス:ここに必要な "OnSize"モジュールはありますか?

ありがとうございました。許可されている/適切な場合、私はあなたが私の場合、勝者にPaypalを介して$ 5を寄付するつもりです。

import wx 

class AddBox(wx.Window): 
    def __init__(self, parent): 
     wx.Window.__init__(self, parent)   

     pbox = wx.BoxSizer(wx.VERTICAL) 

     controlback = wx.Button(self, label="Back") 
     controlforward = wx.Button(self, label="Forward") 

     pbox.AddMany([(controlback, 1, wx.ALL), (controlforward, 1, wx.ALL)]) 

class TestFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, -1, size=(1000, 550)) 

     self.Bind(wx.EVT_SIZE, self.OnSize) 

     pbox0 = wx.BoxSizer(wx.VERTICAL) 
     controlback0 = wx.Button(self, label="Back0") 
     controlforward0 = wx.Button(self, label="Forward0") 
     pbox0.AddMany([(controlback0, 1, wx.ALL), (controlforward0, 1, wx.ALL)]) 
     pbox2 = wx.BoxSizer(wx.VERTICAL) 

     self.scrolling_window = wx.ScrolledWindow(self) 
     self.scrolling_window.SetScrollRate(1,6) 
     self.scrolling_window.EnableScrolling(True,True) 
     self.sizer_container = wx.BoxSizer(wx.VERTICAL) 
     self.sizer = wx.BoxSizer(wx.VERTICAL) 
     self.sizer_container.Add(self.sizer,1,wx.CENTER,wx.EXPAND) 
     self.child_windows = [] 
     for i in range(0,8): 
      wind = AddBox(self.scrolling_window) 
      self.sizer.Add(wind, 0, wx.CENTER|wx.ALL, 5) 
      self.child_windows.append(wind) 

     self.scrolling_window.SetSizer(self.sizer_container) 
     #self.Layout() #not needed? 


     pbox2.AddMany([(self.sizer_container, 1, wx.ALL)]) 

    def OnSize(self, event): 
     self.scrolling_window.SetSize(self.GetClientSize()) 

if __name__=='__main__': 
    app = wx.PySimpleApp() 
    f = TestFrame() 
    f.Show() 
    app.MainLoop() 

答えて

1

ここのコードはかなり畳み込まれており、フォローするのは難しいです。 Wx.Windowを使う必要はほとんどありません。実際、wxPythonを使用して約6年のうちに、私は決してそれを直接使用していません。 PySimpleAppも廃止予定です。とにかく、私はコードを一掃し、下に再実行しました。これがあなたが探しているものかどうかわからない。また、ウィジェットの検査ツールを見てみる必要があります

import wx 
import wx.lib.scrolledpanel as scrolled 

class TestFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, size=(1000, 550)) 
     panel = wx.Panel(self) 

     mainSizer = wx.BoxSizer(wx.VERTICAL) 
     pbox0 = wx.BoxSizer(wx.VERTICAL) 
     controlback0 = wx.Button(panel, label="Back0") 
     controlforward0 = wx.Button(panel, label="Forward0") 
     pbox0.Add(controlback0, 0, wx.ALL) 
     pbox0.Add(controlforward0, 0, wx.ALL) 
     mainSizer.Add(pbox0) 

     self.scrolling_window = scrolled.ScrolledPanel(panel) 
     self.scrolling_window.SetAutoLayout(1) 
     self.scrolling_window.SetupScrolling() 
     self.sizer = wx.BoxSizer(wx.VERTICAL) 
     self.child_windows = [] 
     for i in range(0,8): 
      wind = self.addBox() 
      self.sizer.Add(wind, 0, wx.CENTER|wx.ALL, 5) 
     self.scrolling_window.SetSizer(self.sizer) 

     mainSizer.Add(self.scrolling_window, 1, wx.EXPAND) 
     panel.SetSizer(mainSizer) 

    def addBox(self): 
     pbox = wx.BoxSizer(wx.VERTICAL) 

     controlback = wx.Button(self.scrolling_window, label="Back") 
     controlforward = wx.Button(self.scrolling_window, label="Forward") 

     pbox.AddMany([(controlback, 0, wx.ALL), (controlforward, 0, wx.ALL)]) 
     return pbox 

    def OnSize(self, event): 
     self.scrolling_window.SetSize(self.GetClientSize()) 

if __name__=='__main__': 
    app = wx.App(False) 
    f = TestFrame() 
    f.Show() 
    app.MainLoop() 

:また、私は後者が使いやすいと思うように私はScrolledPanelためにスクロールウィンドウをスワップアウトすることに注意してください。 http://wiki.wxpython.org/Widget%20Inspection%20Tool

EDIT:http://www.blog.pythonlibrary.org/2011/09/20/wxpython-binding-multiple-widgets-to-the-same-handler/

:私は上記のコードは、#3の項目#1と2の世話をすると思うが、私は昨年書いた以下の記事を参照してくださいそれはあなたがこのようなレイアウトの問題を把握するのに役立ちます基本的にループ自体をバインドし、イベントハンドラでevent.GetEventObject()を使用して呼び出し元のウィジェットを返し、その値などを設定することができます。あなたの4番目の質問について、私はいいえ、OnSizeメソッドは必要ないと言っています。あなたはwxPythonでそれをオーバーライドする必要はほとんどありません。私のコード例ではそうではありませんでした。

+0

を(私はいつかこれらにアクセスする必要がある場合はもちろん、あなたがラムダ関数の上にウィジェットを直接渡すことができますが、私はどこかに作成したウィジェットのインスタンスを持っているのが好き)、たとえば、controlbackやcontrolback0が押された場合、addBoxモジュール内のtextctrlをどのように編集することができますか? – mh00h

+0

私はここで何かを紛失しているに違いありません。あなたの例にTextCtrlはどこにありますか? 1つではありません。とにかくランダムボタンを押すと、テキストコントロールを編集することができますか?ボタンを押して編集をオンにしたい場合は、ボタンのデータ構造(おそらく辞書)とそれらにマップされるテキストコントロールを保持する必要があります。次に、ボタンを押すと、テキストコントロールが有効になり、そこにフォーカスが置かれます。 –

+0

ありがとうございます。私はあなたがエレガントに修正したQ1で一番苦労しました。 wxで何をするか教えてくれてありがとう。ウィンドウ、私はそれを追求する方法がわからなかったし、私はここで何が起こっているのか理解を開始する必要がある牽引を私に与えた。 Q3に関しては、あなたの答えが本当に助けになり、複数のtextctrlを自動入力することが可能になりました。いつか私はこのような人々にできる...ありがとう! – mh00h

0

私は動的に作成されたウィジェットにIDを割り当て、このIDを辞書({id:widget})に格納し、コールバック関数としてラムダ関数を渡すかfunctoolsを使います。部分的にIDを "実際の"コールバックに渡します。これは便利ですTRACK-右側に

def __init__(...): 
    self.event_dispatch = dict() 

    ... 

    for id in xrange(500, 508): 
     wind = AddBox(self.scrolling_window, id) 
     ... 
     self.event_dispatch[id] = wind 
     self.scrolling_window.Bind(wx.MY_EVENT, lambda evt: self.on_event(evt, id), id=id) 


def on_event(event, id): 
    widget = self.event_dispatch[id] 
    # do something with widget 
+0

これまでのところとても良い...しかし、これはMike Driscollのコード内にイベントがあるときにはうまくいくが、 "outside in"ではない。 私はcontrolback0からの 'forループ'の中にあったtextctrlにどうやってアクセスできるか分かりません。 (ご協力いただきありがとうございます) – mh00h

関連する問題