2018/03/01
wxPython & XRC でパネルを動的追加する方法
2018/3/5 追記
より使い勝手の良い方法があったので、そちらの方法で実装しなおしたバージョンを作りました。
[wxPython &XRC でパネルを動的追加する方法 with Two Stage Creation | 穀風](https://kokufu.blogspot.com/2018/03/wxpython-with-two-stage-creation.html)
[wxPython &XRC でパネルを動的追加する方法 with Two Stage Creation | 穀風](https://kokufu.blogspot.com/2018/03/wxpython-with-two-stage-creation.html)
Add Panel
ボタンをクリックすると動的に MyPanel
を追加するサンプルを作りました。
MyPanel
はラベルとボタンが一つずつあるだけのシンプルなもので、ボタンをクリックすると自パネルの背景が変わるというお遊びつきです1。
なお、MyPanel
は wxPython & XRC で Custom Frame を作る方法2種+α | 穀風 で紹介した方法で XRC から生成しています2。
ポイントは Add()
でパネルを追加した後、Layout()
を読んで再描画する必要があるという点です3。
これを行わないと、ウィンドウサイズが変わるなどの再描画イベントが走るまで表示が崩れてしまいます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | from random import randrange import wx import wx.xrc as xrc class MyFrame(wx.Frame): def __init__( self , * args, * * kw): super ().__init__( * args, * * kw) self .panels = [] self .sizer = wx.BoxSizer(wx.VERTICAL) self .SetSizer( self .sizer) # Add Panel ボタン button = wx.Button( self , label = "Add Panel" ) button.Bind(wx.EVT_BUTTON, self .on_click) self .sizer.Add(button) def on_click( self , event): panel = MyPanel( self ) panel.set_value( len ( self .panels)) self .sizer.Add(panel, 1 , wx.EXPAND) self .sizer.Layout() self .panels.append(panel) class MyPanel(wx.Panel): def __init__( self , * args, * * kw): super ().__init__( * args, * * kw) this_panel = self class MyPanelXmlHandler(xrc.XmlResourceHandler): def CanHandle( self , node): return self .IsOfClass(node, "wxPanel" ) and node.GetAttribute( 'name' ) = = 'top' def DoCreateResource( self ): self .CreateChildren(this_panel) return this_panel res = xrc.XmlResource( 'MyPanel.xrc' ) res.InsertHandler(MyPanelXmlHandler()) res.LoadPanel( None , "top" ) self .text = xrc.XRCCTRL( self , 'text' ) self .button = xrc.XRCCTRL( self , 'button' ) self .button.Bind(wx.EVT_BUTTON, self .on_click) def set_value( self , value): self .text.SetLabel( str (value)) def on_click( self , event): # ボタンクリックで背景をランダムに変えるお遊び r = randrange( 256 ) g = randrange( 256 ) b = randrange( 256 ) self .SetBackgroundColour([r, g, b]) def main(): app = wx.App( False ) frame = MyFrame( None ) frame.Show() app.MainLoop() if __name__ = = '__main__' : main() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <? xml version = "1.0" ?> < resource > < object class = "wxPanel" name = "top" > < object class = "wxBoxSizer" > < orient >wxVERTICAL</ orient > < object class = "sizeritem" > < object class = "wxBoxSizer" > < object class = "sizeritem" > < object class = "wxStaticText" name = "text" /> </ object > < object class = "sizeritem" > < object class = "wxButton" name = "button" > < label >Click me!</ label > </ object > </ object > < orient >wxHORIZONTAL</ orient > </ object > < option >1</ option > < flag >wxALIGN_CENTRE_HORIZONTAL</ flag > </ object > </ object > </ object > </ resource > |
0 件のコメント:
コメントを投稿