画面に画像ファイルを貼り付ける(ImageAlpha.py)

これから製作する予定のGUI画面が殺風景なのはいやなので、明るくするために色をつける、または画像を貼り付けたいと考えている。そのため、まず単純に画像ファイルを貼り付ける方法を探る。

デモの中からImageAlpha.pyを見つける。これは画像に透明度(αチャンネル)を設定して表示するもののようだ。今回は、画像を貼り付ける部分だけを取り出すことにする。そうしたら次のようになった(ImageAlpha2.py)。

import wx                  # This module uses the new wx namespace
from Main import opj

#-----------------------------------------------------------------
msg = "Some text will appear mixed in the image's shadow..."

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

        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnPaint(self, evt):
        dc = wx.PaintDC(self)
        dc.SetBackground(wx.Brush("WHITE"))
        dc.Clear()

        dc.SetFont(wx.Font(16, wx.SWISS, wx.NORMAL, wx.BOLD, True))
        dc.DrawText("This line shows a test comment.",25,25)
        bmp = wx.Bitmap(opj('bitmaps/toucan.png'))

        dc.DrawBitmap(bmp, 25,100, True)
        
#-----------------------------------------------------------------
def runTest(frame, nb, log):
    win = TestPanel(nb, log)
    return win
#-----------------------------------------------------------------
if __name__ == '__main__':
    import sys,os
    import run
    run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
  • SetBackgroundで背景を白くする。
  • wxBitmapでpngファイルをbmpファイルへ変換する。
  • DrawBitmapでbmpファイルを表示する。

という、単純な流れ。

画像ファイルをタイル状に敷き詰める(DragImage2.py)

次は、一つの画像ファイルをタイルのように画面に敷き詰める方法を試す。
デモの中でDragImage.pyを見つけた。これはまさにやりたいことを含んでいるので、不要な部分を削ぎ落としてゆくことにする。
その結果が次のソース DragImage2.py。

import  wx
import  images

class DragCanvas(wx.ScrolledWindow):
    def __init__(self, parent, ID):
        wx.ScrolledWindow.__init__(self, parent, ID)
#        self.bg_bmp = images.getBackgroundBitmap()
        self.bg_bmp = images.getTestStarBitmap()
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
        
    # tile the background bitmap
    def TileBackground(self, dc):
        sz = self.GetClientSize()
        w = self.bg_bmp.GetWidth()
        h = self.bg_bmp.GetHeight()
        x = 0
        while x < sz.width:
            y = 0
            while y < sz.height:
                dc.DrawBitmap(self.bg_bmp, x, y)
                y = y + h
            x = x + w
    def OnEraseBackground(self, evt):
        dc = evt.GetDC()
        if not dc:
            dc = wx.ClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)
        self.TileBackground(dc)

def runTest(frame, nb, log):
    win = wx.Panel(nb, -1)
    canvas = DragCanvas(win, -1)

    def onSize(evt, panel=win, canvas=canvas): 
        canvas.SetSize(panel.GetSize())

    win.Bind(wx.EVT_SIZE, onSize)
    return win

if __name__ == '__main__':
    import sys,os
    import run
    run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])

やる事は単純なのに結構長い。これ以上どこかを削るとエラーになるので、短くできなかった。
OnEraseBackgroundメソッドで背景をクリアするらしいが、なぜ必要なのかよく分からん...。