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を作るにしても、まず最初にすべきことがある。

起動すると以下のような画面。
img 何のとっかかりもなく、いきなり途方に暮れるわけだが、慌てず騒がず、左上ウインドウのさらに左上にあるアイコンをクリック。
img そのままOK。
img img なんか枠ができた。
img そしてこちらを選んで、先ほどの枠に追加。
img するとこのようなのっぺりした画面に。
img img これで最初の一歩が終了。
ここから、作りたいGUIに合わせて作業をしていく。

作業の前に(日本語は使わないでおこう…)

超絶分かりやすいPythonにも弱点がある。
それは文字コードの扱い。
wxGladeで日本語を書き込むことはできるが、UTF-8なのかShift-JIS(CP932)なのかの扱いが大変に面倒である。
だから、GUI作成時のテキスト、注釈、ボタンは適当な英語で書いておき、実際の処理を書くときに日本語に変えるのがよいと思う。

画面の分割と配置

最終的に以下のようなGUIを作りたいとする。
img このGUIは、まず画面を縦に三分割する。さらに1行目、3行目を横に三分割する。
分割にはパレット上の以下のツールで行う。
img ざくざくと分割して以下のように。
img 以下のように便宜的に番号を振って、
img ①にはテキストを、②にはテキストの枠を、③にはボタン、④には横棒、⑤にはスペース、⑥、⑦にはボタンを置く。
img ツリーはこんなかんじ。
img 名前を変更し、空白(スペーサー)は適当に横に伸ばす。
あとは、経験上、各要素を以下のようにするといいかも。
img img

書き出し

img 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()