ボタンに画像を貼り付ける(BitmapButton.py)

ボタンを押したときに、特定のプログラムが実行されるようにしたい。その前段階としてボタンを装飾しようとする(順序が逆では...という疑念は払拭して)。
BitmapButton.pyを参考にしようと、不要な部分を削ってシンプルな形にする。
その結果が以下のBitmapButton2.pyである(TestPanelクラス付近だけを記す)。

import  wx
import  images
#---------------------------------------------------------------
class TestPanel(wx.Panel):
    def __init__(self, parent, log):        wx.Panel.__init__(self, parent, -1,
                         style=wx.NO_FULL_REPAINT_ON_RESIZE)
        self.log = log

        bmp = images.getTest2Bitmap()
#        mask = wx.Mask(bmp, wx.BLUE)
#        bmp.SetMask(mask)
        b = wx.BitmapButton(self, -1, bmp, (20, 20),
                       (bmp.GetWidth()+10, bmp.GetHeight()+10))
        b.SetToolTipString("This is a bitmap button.")
        self.Bind(wx.EVT_BUTTON, self.OnClick, b)

    def OnClick(self, event):
        self.log.write("Click! (%d)\n" % event.GetId())
  • 画像データはimage.pyというモジュールの中に埋め込まれている(生データ?)
  • maskオブジェクトはどう役に立っているのか不明

任意の画像ファイルをボタンに貼り付けたかったのであるが、このデモだけ見てもやり方は結局全然わからない。

ボタンを押すと特定のプログラムを実行する (Process2.py)

ボタンを押すことで、指定したプログラムを実行するようにしたい。
Processというデモがあるので、必要な部分だけを取り出すことにする。これはExecuteボタンを押したとき、data/echo.pyというコードを実行するようになっている。echo.pyの中身は、自分自身の説明文(__doc__)を書き出しているだけの簡単なもの。

Process.pyを読んでみると、実行するプログラム名を文字列cmdに入れてwx.Process、wx.Execute の記述によって実行させている、と理解した。
Process.pyから今回の目的に沿う部分だけ取り出したのが、以下のProcess2.py(TestPanelクラスの部分のみを掲載)。

class TestPanel(wx.Panel):
    def __init__(self, parent, ID, log):
        wx.Panel.__init__(self, parent, ID)
        self.log = log

        self.process = None
        self.Bind(wx.EVT_IDLE, self.OnIdle)

        # Make the controls
        prompt = wx.StaticText(self, -1, 'Command line:')
        self.cmd = wx.TextCtrl(self, -1, 'python -u data/echo.py')
        self.exBtn = wx.Button(self, -1, 'Execute')

        self.out = wx.TextCtrl(self, -1, '',
                               style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_RICH2)

        self.Bind(wx.EVT_BUTTON, self.OnExecuteBtn, self.exBtn)

        # Do the layout
        box1 = wx.BoxSizer(wx.HORIZONTAL)
        box1.Add(prompt, 0, wx.ALIGN_CENTER)
        box1.Add(self.cmd, 1, wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 5)
        box1.Add(self.exBtn, 0)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(box1, 0, wx.EXPAND|wx.ALL, 10)
        sizer.Add(self.out, 1, wx.EXPAND|wx.ALL, 10)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)

    def OnExecuteBtn(self, evt):
        cmd = self.cmd.GetValue()

        self.process = wx.Process(self)
        self.process.Redirect();
        pid = wx.Execute(cmd, wx.EXEC_ASYNC, self.process)
        self.log.write('OnExecuteBtn: "%s" pid: %s\n' % (cmd, pid))

    def OnIdle(self, evt):
        if self.process is not None:
            stream = self.process.GetInputStream()

            if stream.CanRead():
                text = stream.read()
                self.out.AppendText(text)

とりあえず動作することは確認したが、なぜかものすごく遅くなってしまったようだ。何かの処理に時間がかかっているようだ。
何なのか、まだよく分からないメソッドがあるけど、動いたからOK。