CTC 教育サービス
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes
こんにちは、吉政創成 菱沼です。
今回も「いちばんやさしいPython入門教室(大澤 文孝氏著) 」を片手に勉強していきます。
前回は「クラス」と「オブジェクト」の概念を学ぶ前の準備という事で、tkinterのcanvasを使って動作を確認してみました。
今回はcanvas上にマウスでクリックして円を描くという処理を作っていきます。
以前、ヒット&ブローのプログラムを作る際、ボタンをクリックするとメッセージボックスが表示されるという動作を作りました。(参考)
こういったユーザーがした操作で発生する処理(関数を実行する)のことを「イベント(event)処理」というそうです。今回作ろうとしているキャンバス上でクリックしたところに円を描くという動作は前回とは違う関数を使用するようですが、これも「イベント処理」の一つになります。
引用------
P.189
ボタンの場合「command=」に関数名を記述しました。(中略)
それに対してキャンバスの場合は、bindメソッドを使って、「イベント名」と「実行したい関数」とを結びつけます。
>>> canvas.bind(イベント名, 関数名)
このようにbindメソッドを使うのは、キャンバスではクリック以外にもダブルクリックなど、そのほかのイベントもあるためです。
イベント名は、「キーの装備」「イベント」「種類」をマイナス記号でつなげ、全体を「<」「>」で囲んだ書式で指定します。
「キーの装飾」とは[shift][ctrl][alt]など、一緒に押されたキーの状態を示します。必要ないときは(これらのキーが押されたことを判定する必要がないときは)、省略できます。「イベント」とはイベントの種類のこと、「種類」とは、ボタンやキーの種類です。
(中略)
たとえば、マウスの左ボタンでクリックされたときに「click」という名前の関数を実行したいなら次のように記述します。
>>> canvas.bind(“<Button-1>”, click)
クリックされたときに、click関数が実行されるようになります。
------
>>> canvas.bind(“<Button-1>”, click)
の<>で囲まれた部分ですが、[Button]が「イベント」に当たる部分です。[Button]の意味はマウスポインタの押下、[1]に当たる部分は「種類」を示すものだそうです。[Button]の種類である[1]がさすものはマウスの左クリックということになります。
(clickは後ほど出てきますが、関数名として指定されている部分です。)
このイベントの種類についてはテキストに一覧が載っていましたので抜粋して転記します。
イベント |
意味 |
種類 |
Button / ButtonPress |
マウスのボタンを押された |
1:左ボタン<Button-1> 2:中央ボタン<Button-2> 3:右ボタン<Button-3>(※) |
ButtonRelease |
マウスのボタンが離された |
|
Key / KeyPress |
キーボードのキーが押下された |
指定したいキー 例)aキー:<KeyPress-a> Ctrl+a:<Control-Key-a> Ctrl、Shift、Altをつなげたい場合は「-」でOK。 |
KeyRelease |
キーボードのキーが放された |
|
Enter |
領域内にマウスポイントが入った |
|
Leave |
領域内からマウスポイントが出た |
|
Motion |
領域内でマウスポインタが動いた |
※テキストでは2が右、3が中央となっていますが、確認してみると、2は中央、3が右でした。
ちなみに使用できるイベントの一覧を出すこともできるようです。
以下の参考サイトで方法が書かれていたので試してみました。
Tkinter の使い方:利用可能なイベントやイベントが発生するタイミングを調べる|だえうホームページ
それがこちら。結構あります。
では早速、キャンバスをクリックすると円を描くという処理を作っていきます。
マウスでクリックするというイベントは先で引用した[>>> canvas.bind(“<Button-1>”, click)]が該当します。
ここにある[click]はdefで作られた自作関数の関数名です。これによってマウスクがクリックされると[click]関数が走るような設定になります。
これは以前、ボタンをクリックするとメッセージボックスを表示するという処理と同じ流れですね。
ただButtonウィジェットは「commandオプション」が使えるため、「commandオプション」でイベントと処理を紐づけましたが、「bind」であればすべてのウィジェットに対しての処理が紐づけられるそうです。
参考:【Tkinter】bindメソッドによるトリガーイベントとコールバック関数の紐づけ|電脳世界
今回は「bind」を使って同じような流れで処理を書いてあげることになるようです。
引用-----
サンプルコードから抜粋(P.190,191,192)
def click(event):
canvas.create_oval(event.x - 20, event.y - 20, event.x + 20, event.y + 20,
(中略)
canvas.bind("<Button-1>", click)
「event」という引数として受け取る書式にしておきます。
Eventには、クリックされたときの情報が渡されます。具体的には、
・「event.x」がクリックされた場所のX座標
・「event.y」がクリックされた場所のY座標
これらの座標をそれぞれ示します。そこでcreate_ovalメソッドを使って、この座標に円を描画すれば、クリックされた場所に円が描画されます。
------
※中略した部分にはウィンドウとキャンバスの設定が記述されています。ここでは省略。
※緑字は任意の名称のため、別名でもOKです。
ovalは円を描くメソッドで、書式は「create_oval(x1,y1,x2,y2,オプション)」です。
なので、サンプルコードの意味は「マウスでクリックされた場所から半径20の正円を描く」という事になりますね。
これを実行したのが下の画像です。
確かにクリックしたところに配置されました。
ちなみに<Button-1>を<Button-3>にしたらちゃんと右クリックで動作しました。
次に円を増やすのではなく移動させるような処理をするようです。
引用-----
P.192
円を描くときに、「元々描かれていた円を消す」ようにします。
「消す」というのはわかりにくいですが、「消えたように見せる」ようにプログラムを作ります。いくつかの考え方がありますが、「元々描かれていた場所で、fill=”white”、width=0を指定して、線のない白い円を描画する」という方法が簡単です。キャンバスの背景は白色なのでそうすれば、消えたように見えます。
(中略)
円を消すためには、「前回、どの位置に円を描画したのか」を保存しておく必要があります。そこで、変数xと変数yに「前回、描画した位置」を保存していくことにします。
最初の値は、どのような値でもよいですが、ここでは仮に、キャンバスの中心となる(300,200)としました。
(中略)
click関数内では、この変数xと変数yを使いたいので、グローバル宣言(global)をしています。
------
グローバル宣言について振り返りたい方はご参考までに以前の記事をご参照ください。
これについてはサンプルコード内にコメントをつけて確認します。
という事でこれを実行すると、
こんな感じになります。わかりにくいですけれども…。
それでは今回はこちらで終了です。次はタイマーを使って動かす処理をやるようです。
お付き合いいただきありがとうございました。
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes