Aqua風ボタンにしてみる
しばらくぶりにwxPythonのデモを見たら、結構機能が増えていることに気付く。電子掲示版に見られるように、文字列を横に流して表示すること(Ticker)も普通にできるようになっていた。どう実装するのか悩んだのが遠い昔のようだ。1年前ぐらいか?もしかしたらその時にも、すでにTickerが使えたのかな?
今回は、Aqua風ボタンを表示するデモのAquaButton.pyを詳しく見てみる。ただのボタンよりもきれいだから。あんまりボタンだけ凝り過ぎても、全体からしたら浮いてしまうこともあるので、ピンポイントで凝り過ぎるのは注意が必要だ。
AquaButton.pyのオリジナル画面は下のようになる。
ボタンが二つあってどちらもAqua風なのだが、上のボタンはクリックすると明減する。下のボタンは、マウスがボタン上に来るとボタンの色が変化する。
ソースコードを部分的に見ていく。
boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) boldFont.SetWeight(wx.BOLD) for child in self.mainPanel.GetChildren(): if isinstance(child, wx.StaticText): child.SetFont(boldFont)
この部分では単にフォントを決めてるだけなのだろうが、見慣れないことをしている。表示されるのは、太字だけれどもデフォルトのフォントのように見えるのだが...。ここで全部の画面のフォントを決めているだけ、とか。
def OnPulse(self, event): self.btn1.SetPulseOnFocus(event.IsChecked())
メソッドSetPulseOnFocusを使うと、ボタンを押すとボタンが明減するようになる。他のボタンを押すとこの点滅は止まるが、何もしない限り明減し続ける。こうすると見た目はきれいになるが、Windows以外での挙動が不明なのでこれ以上掘り下げるのは止める。マウスがボタン上にあるときに、ボタンの色が変わる方がシンプルでよい。
self.btn1.SetBackgroundColour(wx.Colour(255,255,100)) self.btn1.SetHoverColour(wx.Colour(255,0,000)) self.btn1.SetForegroundColour(wx.Colour(0,0,0))
このように、ボタンの色を直接指定するようにした。HoverColourが、マウスがボタン上にあるときのボタンの色を与える。ForegroundColourは何を指定してもどこにも影響がないように見える。黒(0,0,0)にしてもどこかが真っ黒になるわけでもないし。
コードをシンプルにするために、余計な部分を削って下のようにした。
import wx import os import sys bitmapDir = os.getcwd() try: from agw import aquabutton as AB except ImportError: import wx.lib.agw.aquabutton as AB class AquaButtonDemo(wx.Frame): def __init__(self): width, height = 150, 170 wx.Frame.__init__(self, None, title='test', size=wx.Size(width, height)) self.mainPanel = wx.Panel(self) self.mainPanel.SetBackgroundColour(wx.WHITE) bitmap = wx.Bitmap( os.path.normpath(os.path.join(bitmapDir, "aquabutton.png")), wx.BITMAP_TYPE_PNG) self.btn1 = AB.AquaButton(self.mainPanel, -1, bitmap, 'button') self.btn1.SetBackgroundColour(wx.Colour(000,000,255)) self.btn1.SetHoverColour(wx.Colour(0,255,255)) self.btn1.SetForegroundColour(wx.Colour(0,0,0)) self.btn2 = AB.AquaButton(self.mainPanel, -1, bitmap, 'button') self.btn2.SetBackgroundColour(wx.Colour(000,000,255)) self.btn2.SetHoverColour(wx.Colour(0,255,255)) self.btn2.SetForegroundColour(wx.Colour(0,0,0)) self.DoLayout() self.BindEvents() def DoLayout(self): mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(self.btn1, 0, wx.ALIGN_LEFT|wx.ALL, 5) mainSizer.Add(self.btn2, 0, wx.ALIGN_LEFT|wx.ALL, 5) self.mainPanel.SetSizer(mainSizer) mainSizer.Layout() def BindEvents(self): self.Bind(wx.EVT_BUTTON, self.OnButton1, self.btn1) self.Bind(wx.EVT_BUTTON, self.OnButton1, self.btn2) def OnButton1(self, event): obj = event.GetEventObject() class Application(wx.App): def OnInit(self): frame = AquaButtonDemo() frame.Show(True) self.SetTopWindow(frame) return True def main(): app = Application(0) app.MainLoop() if __name__ == '__main__': main()