アプリのメニュー画面とか入力画面とかで、ボタンやチェックボックスなどを別途定義してある項目内容に応じて変動させたい場合がある。
たとえば、何らかの商品に区分をつけて入力させる場合に、新しい区分を後でデータベース上に追加したら、それが入力画面に出てくるとか。
プログラムを起動させるメニュー画面で登録プログラムを追加・削除したりとかで、いちいちプログラム内にハードコードしてあるものをいじらずに、JSONなどの定義ファイルから読み込んで表示させるとか。
それをwxPythonでやってみたのが下記のコード。
もとにしたコードはコレ。
python - Dynamically populating widgets, how to then access them? - Stack Overflow
import wx import math def btn_click(event): # eventで渡されるidでウィジェットオブジェクトを指定 btn_obj = wx.FindWindowById(event.GetId()) wx.MessageBox("ボタンラベル:" + btn_obj.Label + "\nリスト名:" + button_list[button_id.index(event.GetId())]) # ボタンの数・内容定義 cont = [] for i in range(20): cont.append(["ボタン" + str(i + 1), "button " + str(i + 1)]) application = wx.App() frame = wx.Frame(None, wx.ID_ANY, 'テスト', size=(600, 500)) panel = wx.Panel(frame, wx.ID_ANY) panel.SetBackgroundColour('#AFAFAF') base = wx.BoxSizer(wx.VERTICAL) title = wx.StaticText(panel, wx.ID_ANY, 'ボタンたくさん', style=wx.TE_CENTER) tfont = wx.Font(14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) title.SetFont(tfont) base.Add(title, flag=wx.SHAPED | wx.ALIGN_CENTER | wx.ALL, border=10) pfont = wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) # 列数 指定及びボタン数に応じて行数rowsを変動させる gridcol = 3 rownum = lambda x : int(math.ceil(len(cont) / x)) buttons = wx.GridSizer(rows=rownum(gridcol), cols=gridcol, gap=(0, 0)) # ボタンの動的配置 button_id = [] button_list = [] for ls in cont: button = wx.Button(panel, wx.ID_ANY, ls[0]) button.SetFont(pfont) button.Bind(wx.EVT_BUTTON, btn_click) buttons.Add(button, proportion=1, flag=wx.SHAPED | wx.ALIGN_CENTER | wx.ALL, border=5) # wigetのidと対応するpgnameを記憶 button_id.append(button.GetId()) button_list.append(ls[1]) base.Add(buttons, proportion=1, flag=wx.SHAPED | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_TOP | wx.ALL, border=10) panel.SetSizer(base) panel.Layout() base.Fit(panel) frame.Centre(wx.BOTH) frame.Show() application.MainLoop()
思ってたよりは簡単にできたかなと。
ここんとこ、ずっとwxFormBuilder使っててイチから画面のプログラムを書いておらず、いい復習になった。