pythonのtkinterでドラッグアンドドロップで画像を表示するイメージビューワー

コンピュータ

ドラッグアンドドロップとキャンバスを組み合わせて画像を表示させてみたいと思います。

# tkinter09.py

# ドラッグアンドドロップで画像を表示するイメージビューワー

import tkinter as tk
from tkinterdnd2 import DND_FILES, TkinterDnD

class Application(TkinterDnD.Tk):
    def __init__(self):
        super().__init__()

        self.drop_target_register(DND_FILES)
        self.dnd_bind('<<Drop>>', self.drop)

        self.geometry("512x512")
        self.canvas = tk.Canvas(self, bg='blue')
        self.canvas.pack()
        self.canvas.place(x=0, y=0, relwidth=1.0, relheight=1.0)


    def drop(self, event):
        self.path = event.data

        if (self.path[0] == '{'):
            l = len(self.path) - 1
            self.path = self.path[1:l]
        print(f"{self.path}")
        self.img = tk.PhotoImage(file=self.path)
        self.canvas.create_image(0, 0, image=self.img, anchor=tk.NW)

if __name__ == "__main__":
    app = Application()
    app.mainloop()

スクリプトを実行すると背景が青色のウィンドウ表示される。

画像ファイル(PNG)をエクスプローラーなどからウィンドウへドラッグアンドドロップする。

画像が表示される。

実はこれがやりたくてtkinterの学習を始めたのですが、スクリプト言語の柔軟性のおかげで試行錯誤してなんとなく動くものが出来ました。
これだけのスクリプトですが、つまづいた点がいくつかありまして、まずドラッグアンドドロップしたファイルのパスが存在しない問題です。
ドラッグアンドドロップですのでファイルが存在しないことは無いはずなのですが、パスをよく見ると前後に{}で囲まれています。
調べたところパスに日本語が含まれている場合発生する現象のようです。(Windowsで確認)最初の1文字目を見て{}を取り除くコードを追加しました。
つぎに、tk.PhotoImageの戻り値の画像オブジェクトをローカル変数に代入すると画像が表示されない現象が発生しました。調べたところ画像が表示される前に画像オブジェクト破棄されているとのこと、selfのメンバーにすることで表示されるようになりました。
その後いろいろな画像を表示してみましたが、表示されるファイルと表示されないファイルがありました。こちらはpngファイルは対応していますが、jpgが対応していないことが理由でした。

コメント