PlateButtonを試してみる
ボタン上に、画像と文字列を同時に表示させる方法を検討する。
画像か文字列のどちらか一方を表示させるのは、これまでの方法(http://d.hatena.ne.jp/Megumi221/20100211)で可能であることが分かった。でも同時に表示させている例はすぐには見当たらない。
起動するとこのような画面が開く(昔作った)コード(の一部)をベースに今回の改良を行う。以下はソース。
import wx class MyApp(wx.PySimpleApp): def OnInit(self): width, height = 250, 150 self.Frm = wx.Frame(None, -1, "wxPython", size=wx.Size(width, height)) VSizer = wx.BoxSizer(wx.VERTICAL) self.TxtCtl1 = wx.TextCtrl(self.Frm, -1, "", size=(235,-1), style=wx.TE_RIGHT) self.Btn = wx.Button(self.Frm, -1, "check") self.Btn.Bind(wx.EVT_BUTTON, self.Decision) VSizer.Add(self.TxtCtl1, 0, wx.ALL, 2) VSizer.Add(self.Btn, 0, wx.ALL, 2) self.Frm.SetSizer(VSizer) self.Frm.Show() return True def Decision(self, event): print "pushed !" app = MyApp() app.MainLoop()
wxPythonデモの中から、画像と文字を同時に表示させているサンプルを探す。唯一、PlateButtonDemo.pyでやっているのを見つける。デモコードの説明文は以下の通り。
Editra Control Library: PlateButton
The PlateButton is a custom owner drawn flat button, that in many ways emulates the buttons found the bookmark bar of the Safari browser. It can be used as a drop in replacement for wx.Button/wx.BitmapButton under most circumstances. It also offers a wide range of options for customizing its appearance, a description of each of the main style settings is listed below.
あまりよく分からないが、普通のボタンよりきれいに表示できるのだな、きっと。
基本的にはwxButtonをコメントアウトして、代わりにPlateButtonとする。修正は簡単だ。下記のコードの通り修正した。適当なPNG画像を用意しておく。
import wx import wx.lib.platebtn as platebtn class MyApp(wx.PySimpleApp): def OnInit(self): width, height = 250, 150 self.Frm = wx.Frame(None, -1, "wxPython", size=wx.Size(width, height)) VSizer = wx.BoxSizer(wx.VERTICAL) self.TxtCtl1 = wx.TextCtrl(self.Frm, -1, "", size=(235,-1), style=wx.TE_RIGHT) # Button styles default = platebtn.PB_STYLE_DEFAULT gradient = platebtn.PB_STYLE_GRADIENT # plate button bImage = wx.Bitmap('test.png') self.Btn = platebtn.PlateButton(self.Frm, -1, "check", bImage, style=gradient) #self.Btn = wx.Button(self.Frm, -1, "check") self.Btn.Bind(wx.EVT_BUTTON, self.Decision) #このままでは何も起こらず。 VSizer.Add(self.TxtCtl1, 0, wx.ALL, 2) VSizer.Add(self.Btn, 0, wx.ALL, 2) self.Frm.SetSizer(VSizer) self.Frm.Show() return True def Decision(self, event): print "pushed !" app = MyApp() app.MainLoop()
起動すると、下のように表示される。背景の色を付けないとボタンかどうか判別できない状態だが、ちゃんと表示されている。
だが、なぜかボタンを押したときに何も起こらない。wxButtonのときにように、
self.Btn.Bind(wx.EVT_BUTTON, self.Decision)
としてはダメなようだ。こうではなく、
self.Bind(wx.EVT_BUTTON, self.Decision) # これだと動作する。
とすると、ちゃんとイベントがself.Decisionに結び付くようだ。
ボタンが一つだけの場合には単純にこうすれば問題ないが、ボタンが複数あってそれぞれのイベントに伴い実行される処理が異なるときはちょっと面倒なことになる(自分が今までやってきた方法では、ボタン毎にBindを定義していたので)。どのボタンを押してもこの場合だとDecisionに飛ぶので、そこでどのボタンが押されたのかを判別して(ちゃんとボタンのIDを決めておけば、event.GetId()で判断できる)から場合分けをして、それぞれの処理を実行するようにする方法が考えられる。処理が2段階になってしまうが、しょうがないか。でもこの方がスマートかとも思う。デバッグがしやすいかな?