とある科学の備忘録

とある科学の備忘録

CやPythonのプログラミング、Arduino等を使った電子工作をメインに書いています。また、木製CNCやドローンの自作製作記も更新中です。たまに機械学習とかもやってます。

【Python】Tkinker第5回 ウィジェットを使用してマウスイベントを作成

Tkinkerは、Pythonでインターフェースを作成するツールキットの1つです。

今回は、Tkinkerで作ったアプリケーションに、マウス入力を加えてみます。

マウスでクリックした場所を取得し、それをprintするプログラムです。

1.サンプルプログラム

import tkinter

class MyApp1(tkinter.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.pack()

        #キャンバスを作成
        self.canvas = tkinter.Canvas(root, bg="black", height=200, width=400)
        
        #キャンバス上で左っくされたときにイベント発生
        self.canvas.bind('<Button-1>', self.mouse_canvas)
        
        self.canvas.create_rectangle(10, 20, 100, 50, fill = 'red')
        self.canvas.pack()
        
        #ラベルを作成
        self.label = tkinter.Label(root, bg = "white", height = 50, width = 300, text="right click me!")
        #右クリックでイベント発生
        self.label.bind('<Button-3>', self.mouse_label)
        self.label.place(x=200, y=100)
        self.label.pack()

        
    def mouse_canvas(self, event):
        #キャンバスを左クリックしたときの処理
        print("Left clicked on the canvas -> (" + str(event.x) + ", " + str(event.y) + ")")
        
    def mouse_label(self, event):
        #ラベルを右クリックしたときの処理
        print("Right clicked on the label-> (" + str(event.x) + ", " + str(event.y) + ")")
        

root = tkinter.Tk()
root.geometry("400x300") #Windowのサイズ設定
root.title("Let's Use a Canvvas") #タイトル作成
app = MyApp1(master=root)
app.mainloop()

2.実行結果

上のプログラムを実行すると、下のような画面が出てきます。
f:id:pythonjacascript:20190203031318j:plain

そして、試しに黒いcanvasの上で左クリックしてみてください。
コマンドプロンプト

Left clicked on the canvas -> (200, 118)

のように表示されるはずです。

また、今度は白い「right click me!」と書かれたボタンを右クリックしてください。

Right clicked on the label-> (260, 54)

またしても、このように表示されるはずです。

出力されたメッセージの文末の(x、y)は、マウスが押されたときの、マウスポインタの座標を表しています。

3.解説

では、↑のプログラムを簡単に解説していきます。

(1)ウィジェットWidget)とは

Tkinkerでマウスイベントを利用するには、「ウィジェットWidget」という考え方が必要です。
ウィジェット」とは、ボタン、キャンバス、ラベルなどの一定の役割を持ったフレームのようなものです。

Tkinkerには、以下のように多くのウィジェットが存在します。

Widget 説明
Button 押しボタン
Canvas キャンバス(図形描画)
Checkbutton チェックボタン
Entry エントリ(1行テキスト入力)
Label ラベル(文字表示)
Listbox リストボックス
Menu メニューバー
OptionMenu オプションメニュー
PanedWindow ペイン区切り
Radiobutton ラジオボタン
Scale スケール(スライダ)
Scrollbar スクロールバー
Spinbox スピンボックス
Text 複数行テキスト入力
Frame フレーム


そして、それぞれのウィジェットに、マウスイベントやキーボードイベント等の割り込み処理を当てはめることができます。


(2)イベントの割り当て

特定のイベント(マウスイベント、キーボードイベント)を割り当てるには、bind()関数を使用します。

例えば、

canvas.bind('<Button-1>', self.mouse_canvas)

と書くと、canvasというウィジェットに、左クリック時のイベント関数として、mouse_canvas()関数を割り当てることができます。

イベントが起こるときの設定を第一引数、イベント発生時に呼び出される関数を第二引数で設定しています。


イベントの種類の設定(第一引数の種類)は以下の通りです。

第一引数 イベント発生条件
Button-1 左クリック
Button-2 マウスホイールクリック
Button-3 右クリック
B-Motion 左クリック状態からドラッグ
ButtonRelease- クリックが離された
Leave ポインタがウィジェット外部に移動

上の表中での「」は、ボタン番号を示しています。
左クリックはx=1、
マウスホイールはx=2、
右クリックはx=3です。


上の表中の値を

canvas.bind('<ButtonRelease-2>', self.mouse_canvas)

のように、「'<>'」を付けて記入してください。


(3)イベントの実行

では、イベントはどのように実行されるのでしょうか。

イベント発生の条件がそろうと、↑の(2)のbind()関数で指定したイベント関数が呼び出されます。

そのとき、引数としてeventを持ちます。

def event_function(event):
    (イベント処理)


マウス関係のイベントの場合、引数eventの中には、以下のような値が格納されています。

変数名 説明
widget クリックされたウィジェット
x, y ウィジェットの左上端からのマウスポイインタの位置
x_root, y_root ウィンドウの左上端からのマウスポインタの位置
num 1=左クリック、2=マウスホイール、3=右クリックによってイベントが発生したことを表す
type イベントタイプ(マウスイベントの場合は

これらは、次に様に扱います。

def event_function(event):
    print("x座標 = " + str(event.x)) #クリックされたx座標表示
    print("y座標 = " + str(event.y)) #クリックされたy座標表示