Python(tkinter006: 位置に基づくラベル制御_渦巻き)
■ラベルの色を渦巻き状に変える。
今回は小さなラベルを使ったサンプルを作ってみた。ラベルの位置に対して制御ができないかというもの。
考え方は次のとおり。
1.ラベルの作成時に、pythonのDictを使用して、ウィジットのIDと位置(行番号、列番号を0でパディングした文字列)をキーと値として入力。
2.渦巻き状にラベルの位置を操作。
3.今のラベル位置に対してDictから対応するウィジットのIDを取得し、そのIDに対してConfigureで背景色を変更させる。
1の具体的なコード。
for i in range(0, COLUMN):
for j in range(0, ROW):
self.widgt1 = ttk.Label(self.base_frame, background="white", font=("Arial", 1))
self.widgt1.grid(column=i, row=j, padx=1, pady=1)
self.label_info_dict.setdefault(str(i).zfill(2) + str(j).zfill(2), self.widgt1.winfo_id())
zfillでパディングをしている。24×24個のラベルの場合、パディングをしないと(2行、12列)と(21行、2列)で同じ212となるけど、パディングを行うと、0212、2102でそれぞれユニークにできる。
3のコード。
for child in self.base_frame.winfo_children():
if child.winfo_id() == self.label_info_dict.get(str(self.column).zfill(2) + str(self.row).zfill(2)):
child.configure(background="#000000")
ウィジットのIDからオブジェクトを取得する方法が分からなかったので、winfo_childrenで全てのオブジェクトを取得した後、IDが一致したものの色を変えるようにしている。この部分は、ボタンの実行部分に入れ、afterメソッドで再帰的に指定している。
最終的なコードサンプルの実行が下の動画。
ちなみに、渦巻き状に位置を操作するコード(2の部分)は下のもの。
if self.flag == "positive":
if self.column == self.turnpoint - 1 and self.row < self.turnpoint - 1:
self.row = self.row + 1
elif self.row == self.turnpoint - 1 and self.column >= self.row:
self.flag = "negative"
else:
self.column = self.column + 1
else:
if self.column == COLUMN - self.turnpoint and self.row >COLUMN - self.turnpoint+1:
self.row = self.row - 1
elif self.row == COLUMN - self.turnpoint+1 and self.column < self.row:
self.turnpoint = self.turnpoint - 1
self.flag = "positive"
else:
self.column = self.column - 1
columnとrowの初期値は0、turnpointの初期値は1辺の最大値(24×24なら24)、flagの初期はpositive。
左上(0, 0)からスタートして、まず行の部分を増やし、行が最大値まで行き列が最大値になっていない場合、次に列を増やす。列も最大まで行ったら、右下まで到達したことになるので、次に数を減らす状態に移る(flagをnegative)にする。同様に数を減らし、左上の部分まで戻ったら、turnpointの数を減らして、折り返す位置を1つ小さくする。
ちゃんと渦巻きのロジックを考えて作ったものではないけど、行と列が同数であれば、行、列の値が偶数、奇数でも最後まで色が変わることを確認した。