Monthly Archives: 12月 2014

[Python] wxGladeでGUIのデザインを

Pocket

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

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

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

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

画面の分割と配置

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

書き出し

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

[メモ][Windows] フリーソフトで年賀状をつくる

Pocket

一年に一度しかやらないのでメモ。
とはいえ、いまどき年賀状なんぞどこかに頼んだ方が楽でなんであるが。

フォトレタッチ: paint.net

http://www.getpaint.net/index.html
フリーのフォトレタッチというとGIMP一択なんだが、高機能すぎて途方に暮れる。
その点paint.netはシンプルだから楽。
paintnet20141223

宛名印刷: Aprint

Aprint
webサイトには20世紀の残り香があるものの、ソフトは必要にして充分。
データはcsvで保存できるから取り回ししやすいし、複数宛先もできる。
フォントも選べるので、はんなり明朝とか、ちょっと変わったフォントを使ってもよい。
aprint20131223

以上

[FreeBSD] 10.1-RELEASEのfreebsd-updateがご乱心した件(消えたlib32の怪)

Pocket

ここ最近にamd64のFreeBSD 10.1-RELEASEでfreebsd-updateを実行すると、①「/usr/lib32/をインストールしようとする」、②「ルートディレクトリを削除しようとする」なんて事が起こる。

いずれも大きな問題はない。

[FreeBSD-Announce] [HEADS UP] freebsd-update issues in 10.1

背景は以上のリンク先で示されるとおりである。

すなわち。
10.1アップグレード用のfreebsd-updateパッチを作る際に「lib32のことをうっかり対象外にしてしまいました!」「結果として10.1にfreebsd-udateでアップグレードした人はlib32が無くなってましたサーセン」ということである。
したがってfreebsd-updateが主張する通りインストールしても問題はない。

一方で、ルートディレクトリを削除しようとする件については中の人もよく分かってないのだが、実害はないとのこと。

以下は参考。
amd64の10.1-RELEASEでfreebsd-updateをすると、以下のように/usr/lib32がインストール対象になった。

The following files will be added as part of updating to 10.1-RELEASE-p2:
/libexec/ld-elf32.so.1
/usr/bin/ldd32
/usr/lib32/Scrt1.o
/usr/lib32/crt1.o
/usr/lib32/crtbegin.o

また、実際にインストールするとこんなメッセージも出る。実害なし。

$ sudo freebsd-update install
パスワード:
Installing updates...rmdir: ///: Is a directory
 done.
$
No tags for this post.