デジタルフォトフレームの動作をwxPythonで実装する(3) -Linuxでは少しまともに動く-

昨日(デジタルフォトフレームの動作をソフトウェア的に実装する - 理想のユーザ・インターフェイスを求めて)のコード実行時のエラーなのだが、うちのMacでだけ起こるエラーのようだ。Linux環境で実行したらエラーが再現されなかった。

(▲Chromeの画像を表示しているところ。画像は本文の内容とは無関係)

  • エラーが起こったMacの実行環境
  • エラーが再現されなかったLinuxでの実行環境

Linux(Debian)では、エラーは出ずクラッシュしないが、画面遷移(画像切り替え)が途中で止まってしまう。マウスをフレームに入れると、画像が切り替わったり、と挙動が安定していない。スレッドを使っているが、うまく実装できていないのかな。

今回のコードでは以下の細かな改良を加えた。

  • 今回の改良点
    • 画像ファイルの形式によって、タイプIDを場合分けしていたのを、wx.BITMAP_TYPE_ANYと指定することで、形式を自動判別する。
    • フレームサイズを固定して、画像サイズがそれに合うようにスケールする。

ソースは以下の通り。

#!/bin/env python
# version 3
import os
import wx
import time
import thread

class MainFrame(wx.Frame):
    def __init__(self, id, title):
        self.w, self.h = 200, 200
        wx.Frame.__init__(self, id, title="Photo Frame",
                          size=wx.Size(self.w, self.h))
        p = wx.Panel(self, -1)

        ebmp = wx.EmptyBitmap(200,200)
        self.sb = wx.StaticBitmap(p, -1, ebmp)

        thread.start_new_thread(self.run, ())

    def run(self):
        n = -1
        while True:
            ph = os.path.join(os.getcwd(), 'picts')
            fls = os.listdir(ph)
            n += 1
            if n >= len(fls):
                n = 0
            pname = os.path.join(ph, fls[n])
            img = wx.Image(pname, wx.BITMAP_TYPE_ANY)
            w = img.GetWidth()
            h = img.GetHeight()
            if w>=h:
                factor = float(self.w)/w
            else:
                factor = float(self.h)/h
            img2 = img.Scale(w*factor, h*factor)

            bmp = img2.ConvertToBitmap()
            self.sb.SetBitmap(bmp)

            time.sleep(10)

class Application(wx.App):
    def OnInit(self):
        frame = MainFrame(None, -1)
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    app = Application(0)
    app.MainLoop()

if __name__ == '__main__':
    main()

この実装のどこが不適切なのか、もう少し検討する。