画像をパラパラ流す

同一ディレクトリ内にある画像を次々と表示させることでパラパラ漫画みたいにするスクリプトです。
そんな意味があるかはわからないけど、習作です。
wxで作ろうとしたけど、すっかり忘れていたので、Tkinterを使っています。

ソースコード

# -*- coding: UTF-8 -*
"""
同一ディレクトリ内の画像を連続して流すことで、動画っぽく見せる。
画像の順番はソートします。
"""

from Tkinter import *
import PIL.Image, PIL.ImageTk
import re, os, sys

# 切り替え速度 [ms]
TIME = 5


def embedded_numbers(s):
    """
    Pythonクックブックからの引用
    """
    re_digits = re.compile(r'(\d+)')
    pieces = re_digits.split(s)
    pieces[1::2] = map(int, pieces[1::2])
    return pieces


class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        # ディクレクトリ内のファイルのリストを取得する
        self.ls = os.listdir(os.getcwd())
        self.ls.remove(os.path.basename(__file__)) # スクリプト名はいらない。。

        # numはリストの何番目を表示しているかの情報を保持
        # startedはアニメーションが始まっているか
        self.num = 0
        self.started = False

        # フレームの設定
        self.la = Label(self)
        self.la.pack()
        self.pack()
        self.bind_all('<1>', self.anime_start)
        self.bind_all('<3>', self.anime_reset)

        self._setting()

    def anime_reset(self, event):
        self.num = 0
        if not self.started:
            self._setting()

    def anime_start(self, event):
        # 右クリックでスタートとストップを切り替える
        if self.started:
            self.started = False
        else:
            self._setting()
            self.after(TIME, self.anime)
            self.started = True

    def anime(self):
        # 始まってるなら画像を変えていく
        if self.started:
            self.num += 1
            if self.num < len(self.ls):
                self._setting()
                self.after(TIME, self.anime)
            else:
                # ファイルを全部表示しきったらnumとstartedをリセット
                self.num = 0
                self.started = False

    def _setting(self):
        # 画像を読み込み、タイトルを変える
        self.image = PIL.ImageTk.PhotoImage(PIL.Image.open(self.ls[self.num]))
        self.la.configure(image=self.image)
        self.master.title(self.ls[self.num] + " - " + "左クリックでスタートストップ。右クリックでリセット")


if __name__ == '__main__':
    app = App()
    app.mainloop()

メモ

os.listdir(ディレクトリのパス)
でそのディレクトリ内の全てのファイルを取得することができます。
そのファイルリストは、スクリプト名も含んでしまっているので、スクリプト名をリストから消しておきます(__file__がスクリプト名)
それをソートして、順番に表示していくわけです。


ファイル名は数字を含んでいます。
例えば、

1.txt, 2.txt, ...., 10.txt, 11.txt, 12.txt, ....., 20.txt, 21.txt

という感じです。
これをそのまま文字列としてソートすると、

1.txt, 10.txt, 11.txt, 12.txt, ....., 2.txt, 20.txt, 21.txt, .....

といった感じで具合が悪いです。
そこで、Pythonクックブックに乗っていた手法を使います。
embedded_numbers関数をkeyにしてソートしています。これにより

1.txt, 2.txt, ....., 10.txt, 11.txt, 12.txt, ......, 20.txt, 21.txt

みたいな感じになります。

Tkinterの使い方は下の参考に示しているページに詳しく書いてありました。

参考

Tkinter 入門: 3. Label だけでタイマーを作ろう
GUI周り、タイマーの処理はほぼコピーみたいな感じです。