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つ小さくする。

ちゃんと渦巻きのロジックを考えて作ったものではないけど、行と列が同数であれば、行、列の値が偶数、奇数でも最後まで色が変わることを確認した。