Pythonのtkinterのcanvasに表示する画像を切り替える

PythonのGUI(tkinter)モジュールのcanvasウィジェットに表示する画像を、プログラムの側から切り替えてみました。

itemconfigでオプションを書き換える

tkinterのcanvasオブジェクトのitemconfigメソッドで、canvasのオプションを変更することができます。

tkinter.canvas.itemconfig(item, options)
変数 内容
item   変更するtkinterのcanvasのID。
options   変更するオプション。

ちょっとわかりにくいので、コードを見てみます。

canvasを1つと、ボタンを3つ配置して、ボタンによって画像を切り替えるプログラムを作ってみます。

画像は プロ生ちゃん です。

import tkinter
import tkinter.ttk
from PIL import Image, ImageTk

class Application(tkinter.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.master.title('tkinter canvas trial')
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        # ボタン
        self.original_button = tkinter.ttk.Button(self, text='Original')
        self.original_button.grid(row=0, column=1)
        self.original_button.bind('<Button-1>', make_original)

        self.gray_button = tkinter.ttk.Button(self, text='Gray Scale')
        self.gray_button.grid(row=1, column=1)
        self.gray_button.bind('<Button-1>', make_grayscale)

        self.blackwhite_button = tkinter.ttk.Button(self, text='Black and White')
        self.blackwhite_button.grid(row=2, column=1)
        self.blackwhite_button.bind('<Button-1>', make_blackwhite)

        # canvas
        self.test_canvas = tkinter.Canvas(self, width=original_image.width, height=original_image.height)
        self.test_canvas.grid(row=0, column=0, rowspan=3)

        # canvasに初期画像を表示
        self.test_canvas.photo = ImageTk.PhotoImage(original_image)
        self.image_on_canvas = self.test_canvas.create_image(0, 0, anchor='nw', image=self.test_canvas.photo)

def make_original(event):
    set_image(event, original_image)

def make_grayscale(event):
    gray_image = original_image.convert('L')
    set_image(event, gray_image)

def make_blackwhite(event):
    THRESHOLD = 174
    gray_image = original_image.convert('L')
    bw_image = gray_image.point(lambda x: 0 if x < THRESHOLD else x)
    set_image(event, bw_image)

def set_image(event, img):
    # canvasの書き換え
    app.test_canvas.photo = ImageTk.PhotoImage(img)
    app.test_canvas.itemconfig(app.image_on_canvas, image=app.test_canvas.photo)


# 画像ファイル読み込み
original_image = Image.open('test_figure.png')

# アプリケーション起動
root = tkinter.Tk()
app = Application(master=root)
app.mainloop()

Applicationクラスにウィジェットの配置の定義をまとめてあります。

各ボタンウィジェットにbindされている関数が、ボタンのクリックイベントによって呼び出されます。Button-1はマウスの左クリックのイベントです。

Applicationクラスの最後に、test_canvas.create_image()というメソッドがあります。このメソッドの戻り値をimage_on_canvasという名前の変数に入れます。この変数が、itemconfigで変更するアイテムのターゲットになります。

各ボタンのイベントから呼び出される各関数は、単純に元画像を変換して、呼び出し元から来たeventオブジェクトと変換画像のオブジェクトをset_imageという関数に投げます。

set_image関数は受け取った画像オブジェクトをtkinter用に変換して、canvasのphotoプロパティにセットします。その後、itemconfigメソッドでcanvasにcanvasのphotoプロパティの中身を描画するよう指示します。

Python 3.7ですが、これで一応動作します。

実際に動かしてみるとこんな感じです。

広告

PythonでGUIカテゴリの投稿