IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

ゼロから歩くPythonの道

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes 

第30回 tkinterのcanvasに複数の円を縦横移動、リストとディクショナリの合わせ技で記述と管理を楽に (菱沼佑香) 2022年3月

こんにちは、吉政創成 菱沼です。
今回も「いちばんやさしいPython入門教室(大澤 文孝氏著) 」を片手に勉強していきます。

「クラス」と「オブジェクト」の概念を学ぶということで、その準備段階として、tkinterのcanvas上に作った円を左右に往復させるという処理を作りました。
今回はこれまでの動きはそのままに、円の数を増やし、複数の円を一つのcanvas上で動かすという処理を作っていきます。

複数の円はディクショナリとリストで管理すれば簡単に

前回までの間にやったのは、
①1つの円を横方向だけに移動させる
②1つの円を縦・横方向に移動させる
という処理でした。

①の場合は、横(X軸)の設定を行えばいいので、必要な変数はX軸の位置を表すxと、移動量を表すdxの2つでした。
②の場合は、横(X軸)と縦(Y軸)の2つ分をそれぞれ位置と移動量を設定してあげなくてはいけないので、x、dx、y、dyの4つの変数が必要でした。

が、これが複数の円を表示する、その上、縦横に移動させるとなると変数4個×円の数となるので正直大変ですし、管理も面倒くさそうです。
そこでディクショナリとリストを使用すれば管理の負担を減らせるそうです。

ディクショナリで一つの円に必要なデータをひとまとめにする

ではまずはディクショナリから。

-----
P.207 引用
「1つの円に関するデータは、ひとまとめにする」という考え方です。
そのための方法として、Pythonの「ディクショナリ(Dictionary)」という機能を使います。ディクショナリは、「キーと値のペア」を、ひとまとめにして管理する仕組みです。
(中略)
ディクショナリは以下の書式で設定します。
>>> 変数名 = { キー名 : 値, キー名 : 値 , ...}
こうして記述すると、そのそれぞれのキーに対して、
>>> 変数名["キー名"]
という書式で参照できる仕組みです。
このようにディクショナリを使うと、関連するデータをひとまとめにしやすくなります。
-----

辞書というだけあってキーが単語、バリューが内容ということですね。
ちなみにキー名はkey、値はvalueとも言うようで、それぞれのペアは[,(カンマ)]で値を区切られています。
後ほど出てくるリストには順序がありますが、ディクショナリには順序がないそうで、値(value)を呼び出すためにはキー名(key)が必要とのこと。

ということで、X座標が400、Y座標が300の位置にdx=1,dy=1の円を作りたい場合にはこう書かれることになります。
>>>ball = {"x" : 400 , "y" :300, "dx" : 1, "dy" : 1}

そして実際に円を描くときには次のように記述されます。
>>> canvas.create_oval(ball ["x"] ? 20, ball ["y"] -20, ball ["x"] + 20, ball ["y"] + 20, "red", width=0)

ディクショナリを使う前が
>>>canvas.create_oval(x - 20, y - 20, x + 20, y + 20, fill="red", width=0)

と書かれていたことを思うと、逆に長くて見にくい...不便じゃない?と思いますし、これを作りたい円の個数分用意するとなるとゾッとします。100個分書けということになったら絶対間違えます。間違えたら見直すのも大変そうです...。
そこでリストの出番なようです。

リストを使えば複数個のディクショナリも一度に管理できる

リストといえば以前取り上げました。
そう...A=[a,b,c,d]のように[]の中に入れた複数の値を変数に保存しているやつです。
呼び出すときにはインデックス番号を使用してA[0]、A[-1]のように書きます。この時の[]に入る値がインデックス番号で、左からなら0,1,2,3、右からなら-1,-2,-3,-4と割り当てられています。

このリストの[]の中に入る値にディクショナリで作った値を入れていく、ということのようです。

------
P.208
リストを使うと、たとえば、次のように記述できます。
balls = [
{"x" : 400, "y" : 300, "dx" : 1, "dy" : 1},
{"x" : 200, "y" : 100, "dx" : -1, "dy" : 1 },
{"x" : 100, "y" : 200, "dx" : 1, "dy" : -1 }
]

こうすると、たとえば、1つ目の円のX座標とY座標は、
balls[0]["x"]
および、以下のように取得できます。
balls[0]["y"]
2つ目の円であれば、
balls[1]["x"]
および、以下のように取得できます。
balls[1]["y"]

よって、たとえば、この1つ目の円を描画するには、以下のように記述できます。
canvas.create_oval(balls[0]["x"] ? 20, balls[0]["y"] ? 20, balls[0]["x"] + 20, balls[0]["y"], "red", width0)

(中略)3つの変数を使う場合と、何ら変わりませんが、違うのはループ処理できるという点です。もし、3つすべてを描画するには、2つずつ取り出して、これをループすればよく、以下のように短く書けます。

for b in balls:
canvas.create_oval(b[0]["x"] ? 20, b[0]["y"] ? 20, b[0]["x"] + 20, b[0]["y"], "red", width0)
-----

ということで、リストの中にディクショナリを入れ、さらにループ処理で繰り返せば[0]の部分は順番に[1]とか[2]のリストが入っていくので、記述も短く済む、ということになります。
さらにディクショナリに色の設定として、「"color" : "red"」を一緒に記述してしまえばもっと簡単!ということだそうです。

そうしてできたのがこちら。

fig01

これを動かすとこうなります。(画像では動かす速度は速くしています。)

fig02

動かす円を増やしたい場合はディクショナリに追加してあげればOKです!
では今回はこちらで終了です。お付き合いいただきありがとうございました。

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes