Python、Perl、Ruby、PHPなどのLight Languageは、俺みたいな素人プログラマでもじゃんじゃんコードを書けるところが素晴らしい。
さらにそのコードがGUIで動くようになるのなら、もっと素晴らしい。
wxGladeでそれができる。wxGladeでGUIを作ってみたので記す。
wxGladeとは
http://wxglade.sourceforge.net/index.php
wxPython向けのGUIデザイナーである。
wxPythonとはPythonのGUIツールキット。
また、GNOMEのGUIツールキットであるGladeが名前に入っている通り、wxGladeの設計思想はGladeに沿っている。
インストール
こちらからどうぞ。
以下の例ではWindowsを使っている。
最初の一歩
どんなGUIを作るにしても、まず最初にすべきことがある。
起動すると以下のような画面。
何のとっかかりもなく、いきなり途方に暮れるわけだが、慌てず騒がず、左上ウインドウのさらに左上にあるアイコンをクリック。
そのままOK。
なんか枠ができた。
そしてこちらを選んで、先ほどの枠に追加。
するとこのようなのっぺりした画面に。
これで最初の一歩が終了。
ここから、作りたいGUIに合わせて作業をしていく。
作業の前に(日本語は使わないでおこう…)
超絶分かりやすいPythonにも弱点がある。
それは文字コードの扱い。
wxGladeで日本語を書き込むことはできるが、UTF-8なのかShift-JIS(CP932)なのかの扱いが大変に面倒である。
だから、GUI作成時のテキスト、注釈、ボタンは適当な英語で書いておき、実際の処理を書くときに日本語に変えるのがよいと思う。
画面の分割と配置
最終的に以下のようなGUIを作りたいとする。
このGUIは、まず画面を縦に三分割する。さらに1行目、3行目を横に三分割する。
分割にはパレット上の以下のツールで行う。
ざくざくと分割して以下のように。
以下のように便宜的に番号を振って、
①にはテキストを、②にはテキストの枠を、③にはボタン、④には横棒、⑤にはスペース、⑥、⑦にはボタンを置く。
ツリーはこんなかんじ。
名前を変更し、空白(スペーサー)は適当に横に伸ばす。
あとは、経験上、各要素を以下のようにするといいかも。
書き出し
Appのプロパティから、LanguageにPython、Output Pathでファイルを指定し、Generate Codeでコード生成。
以下が例。
#!/usr/bin/env python
# -*- coding: CP932 -*-
#
# generated by wxGlade 0.6.8 (standalone edition) on Sun Dec 28 07:13:39 2014
#
import wx
# begin wxGlade: dependencies
import gettext
# end wxGlade
# begin wxGlade: extracode
# end wxGlade
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: MyFrame.__init__
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.panel_1 = wx.Panel(self, wx.ID_ANY)
self.label_1 = wx.StaticText(self.panel_1, wx.ID_ANY, _("input : "))
self.inputfile = wx.TextCtrl(self.panel_1, wx.ID_ANY, "")
self.ChooseButton = wx.Button(self.panel_1, wx.ID_ANY, _("Choose"))
self.static_line_1 = wx.StaticLine(self.panel_1, wx.ID_ANY)
self.go = wx.Button(self.panel_1, wx.ID_ANY, _("Run"))
self.exit = wx.Button(self.panel_1, wx.ID_ANY, _("Cancel"))
self.__set_properties()
self.__do_layout()
self.Bind(wx.EVT_BUTTON, self.choosefile, self.ChooseButton)
self.Bind(wx.EVT_BUTTON, self.goclicked, self.go)
self.Bind(wx.EVT_BUTTON, self.exitclicked, self.exit)
# end wxGlade
def __set_properties(self):
# begin wxGlade: MyFrame.__set_properties
self.SetTitle(_("frame_1"))
self.ChooseButton.SetToolTipString(_("choose a file "))
# end wxGlade
def __do_layout(self):
# begin wxGlade: MyFrame.__do_layout
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_2 = wx.BoxSizer(wx.VERTICAL)
sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
sizer_3.Add(self.label_1, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
sizer_3.Add(self.inputfile, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
sizer_3.Add(self.ChooseButton, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
sizer_2.Add(sizer_3, 1, wx.EXPAND, 5)
sizer_2.Add(self.static_line_1, 0, wx.EXPAND, 5)
sizer_4.Add((200, 20), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
sizer_4.Add(self.go, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
sizer_4.Add(self.exit, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
sizer_2.Add(sizer_4, 1, wx.EXPAND, 0)
self.panel_1.SetSizer(sizer_2)
sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
sizer_1.Fit(self)
self.Layout()
# end wxGlade
def choosefile(self, event): # wxGlade: MyFrame.
print "Event handler 'choosefile' not implemented!"
event.Skip()
def goclicked(self, event): # wxGlade: MyFrame.
print "Event handler 'goclicked' not implemented!"
event.Skip()
def exitclicked(self, event): # wxGlade: MyFrame.
print "Event handler 'exitclicked' not implemented!"
event.Skip()
# end of class MyFrame
if __name__ == "__main__":
gettext.install("app") # replace with the appropriate catalog name
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
frame_1 = MyFrame(None, wx.ID_ANY, "")
app.SetTopWindow(frame_1)
frame_1.Show()
app.MainLoop()