【Python】customtkinter:長さを入力して立方体を描画するツール

■概要

customtkinterにて、長さを入力するフォームを作成し、入力した長さに応じて立方体を描画するツールを作成する。

以降、このツールを立方体作成ツールと呼ぶ。

■画面イメージ

以下に、立方体作成ツールの画面イメージを示す。


▼メイン画面(立方体作成ツール)

  • メイン画面の「立方体作成ツール」画面の画面サイズは「300×100」とする。
  • 「長さ:」ラベル右側のテキストボックスを配置する。
  • テキストボックスに数字を入力し、「作成」ボタンを押下すると、立方体が作成されるようにする。
  • 入力値の条件は、正の整数とする。

▼立方体作成画面

  • メイン画面の「立方体作成ツール」画面より入力した数値に応じて、「立方体作成画面」の画面サイズを設定する。
    なお、「立方体作成画面」の画面サイズの計算式は、縦横共通で以下の「画面サイズ計算式」とする(※詳細は、▼画面サイズの計算について参照)。
  • メイン画面の「立方体作成ツール」画面より入力した数値に応じて、立方体を描画する。
  • 描画した立方体の後ろ側は点線で示す。
  • 立方体描画の開始は、x座標については、「画面サイズ/2」の位置からとし、y座標については、「5」の位置からとする(※詳細は、▼立方体描画の開始位置について参照)。
画面サイズ計算式

立方体作成に伴う各種計算事項について、以下に示す。

今回作成する立方体における、各辺の長さは、「入力値」とし、下部の頂点と底線(青線)とのなす角度は45度とする。


▼画面サイズの計算について

上図の通り、最長の長さは正方形の斜辺(赤線)と入力値(黒線)の合計である。
正方形の斜辺(赤線)は、三平方の定理にて算出可能である。
画面サイズについては、バッファとして、さらに「10」を加算するものとする。


▼立方体描画の開始位置について

立方体描画の開始位置は、以下の図の通りとする。


▼立方体の描画について

立方体を描画するにあたり、「縦」・「横」・「高さ」を定義する。

今回、「customtkinter」の「CTkCanvas().create_line()」を描画に使用する。
「create_line()」の仕様上、画面をx,y軸と見立てた時、以下のように記載する必要がある。

create_line(開始のx座標, 開始のy座標, 終了のx座標, 終了のy座標)

すなわち、「高さ」については、そのまま「入力値」を使用するが、「縦」・「横」については、三平方の定理にて求めたx座標およびy座標を使用する。

例えば、図の頂点①(x1, y1)から頂点②へ線を描画する場合は、下図の通りとなる。

※customtkinterのy座標は、以下図のように、下方向に進むにつれて増加していくことに注意。

■フローチャート

ここでは、実装するプログラムの「メイン処理」・「立方体作成処理」・「数字チェック処理」について、フローチャートを示す。

▼メイン処理

「メイン処理」のフローチャートを以下図に示す。

▼立方体作成処理

「立方体作成処理」のフローチャートを以下図に示す。

▼数字チェック処理

「数字チェック処理」のフローチャートを以下図に示す。

■プログラム仕様

ここでは、実装するプログラムの「メイン処理」・「立方体作成処理」・「数字チェック処理」について、プログラム仕様を示す。

▼メイン処理

「メイン処理」のプログラム仕様を以下表に示す。

入力処理内容出力
画面のカラーテーマを設定する。
カラーテーマ:light
メイン画面をインスタンスする。
メイン画面の範囲を設定する。
x座標:300
y座標:100
メイン画面のタイトルを設定する。
タイトル:立方体作成ツール
入力値の値を保持する。
型:文字列型(StringVar)
入力のラベルを設定する。
表示名:「長さ:」
表示位置:
x=45
y=20
入力用のテキストボックスを設定する。
表示位置:
x=85
y=20
「作成」ボタンを設定する。
表示名:「作成」
表示位置:
x=85
y=60
ボタン押下時の処理:立方体作成処理
メイン画面の表示【coustomtkinter】
メイン画面

▼立方体作成処理

「立方体作成処理」のプログラム仕様を以下表に示す。

入力処理内容出力
【数字チェック処理】を呼び出す。
▼条件分岐:戻り値
【0の場合】
【メイン画面】
入力値
入力した数字をfloat型で取得する。
立方体作成画面の範囲を算出する。
範囲の形式は「XxY」とする。
※詳細は▼画面サイズの計算について参照。
立方体作成画面をインスタンスする。
立方体作成画面の範囲を設定する。
立方体作成画面のタイトルをセットする。
タイトル:立方体作成画面
立方体を描くキャンバスを設定する。
立方体描画開始のx,y座標セットする。
x座標:画面サイズ/2
y座標:5
※詳細は、▼立方体描画の開始位置について参照。
縦と横の辺の長さを算出する(三平方の定理)。
※詳細は、#▼立方体の描画について参照。
立方体上部の「^」部分を描画する。
※イメージ図
中間x,y座標をセットする。
立方体上部の「V」部分を描画する。
※イメージ図
中間y座標をセットする。
立方体上部と下部をつなげる「|」部分を描画する。
※イメージ図
中間y座標をセットする。
立方体下部の「◇」部分を描画する。
※イメージ図
立方体作成画面を表示する。【画面】
立方体作成画面
▲条件分岐:ここまで

▼数字チェック処理

「数字チェック処理」のプログラム仕様を以下表に示す。

入力処理内容出力
【メイン画面】
入力値
入力値を取得する。
▼条件分岐:入力値
【整数ではない場合】
警告メッセージを出力する。【MsgBox】
整数ではない
戻り値として「1」を返す。
▲条件分岐:ここまで
▼条件分岐:入力値
【0以下の場合】
警告メッセージを出力する。【MsgBox】
0以下である
戻り値として「2」を返す。
▲条件分岐:ここまで
戻り値として「0」を返す

■サンプルコード

立方体作成ツールのサンプルコードを以下に示す。

import math

import customtkinter as ctk
import tkinter.messagebox as msg

# 数字チェック処理
def InputNumChk():
    # 入力値を取得
    inputdata = str_length.get()

    # 数字以外入力されていたら1
    if not inputdata.isdigit():
        msg.showinfo("注意", "入力値は整数のみ設定してください")
        return 1
    # 0以下が入力されたら2
    if not int(inputdata) > 0:
        msg.showinfo("注意", "入力値は0より大きい値を設定してください")
        return 2
    
    return 0


# 立方体作成処理
def MakeCube():
    # 数字チェック
    chknum = InputNumChk()
    # 数字の場合(=0)
    if chknum == 0:
        # 入力した数字をfloat型で取得
        float_length = float(str_length.get())

        # 立方体作成画面の範囲を算出
        tmp_range = int(float_length * math.sqrt(2) + float_length + 10)
        base_range = str(tmp_range) + 'x' + str(tmp_range)

        # 立方体作成画面のインスタンス
        base_cube = ctk.CTk()
        # 立方体作成画面の範囲を設定
        base_cube.geometry(base_range)

        # 立方体作成画面のタイトルセット
        base_cube.title("立方体作成画面")

        # 立方体を描くキャンバス設定
        canvas = ctk.CTkCanvas(base_cube)
        canvas.pack(fill=ctk.BOTH, expand=True)

        # 立方体描画開始のx,y座標セット
        start_x = tmp_range / 2
        start_y = 5

        # 三平方の定理:辺の長さ算出(1:√2)
        distance = float_length / math.sqrt(2)

        # 上部の「^」部分を描画
        canvas.create_line(start_x, start_y, start_x - distance, start_y + distance, width=1)
        canvas.create_line(start_x, start_y, start_x + distance, start_y + distance, width=1)

        # 中間x,y座標をセット
        start_x1 = start_x - distance
        start_x2 = start_x + distance
        start_y1 = start_y + distance

        # 上部の「V」部分を描画
        canvas.create_line(start_x1, start_y1, start_x1 + distance, start_y1 + distance, width=1)
        canvas.create_line(start_x2, start_y1, start_x2 - distance, start_y1 + distance, width=1)

        # 中間y座標をセット
        start_y2 = start_y1 + distance

        # 上部と下部をつなげる「|」部分を描画(後ろ側は点線)
        canvas.create_line(start_x1, start_y1, start_x1, start_y1 + float_length, width=1)
        canvas.create_line(start_x2, start_y1, start_x2, start_y1 + float_length, width=1)
        canvas.create_line(start_x, start_y2, start_x, start_y2 + float_length, width=1)
        canvas.create_line(start_x, start_y, start_x, start_y + float_length, width=1, dash=(5, 3))

        # 中間y座標をセット
        start_y3 = start_y1 + float_length

        # 下部の「◇」部分を描画(後ろ側は点線)
        canvas.create_line(start_x1, start_y3, start_x, start_y2 + float_length, width=1)
        canvas.create_line(start_x2, start_y3, start_x, start_y2 + float_length, width=1)
        canvas.create_line(start_x1, start_y3, start_x, start_y + float_length, width=1, dash=(5, 3))
        canvas.create_line(start_x2, start_y3, start_x, start_y + float_length, width=1, dash=(5, 3))

        # 立方体作成画面を表示
        base_cube.mainloop()
    

# メイン処理
if __name__ == '__main__':
    # カラーテーマを設定
    ctk.set_appearance_mode("light")

    # メイン画面のインスタンス
    root = ctk.CTk()
    # メイン画面の範囲を設定
    root.geometry("300x100")

    # メイン画面のタイトル設定
    root.title("立方体作成ツール")

    # 入力値の値を保持(文字列型)
    str_length = ctk.StringVar()

    # 入力のラベルを設定
    length_label = ctk.CTkLabel(root, text="長さ:")
    length_label.place(x=45, y=20)
    # 入力用のテキストボックスを設定
    length_entry = ctk.CTkEntry(root, textvariable=str_length)
    length_entry.place(x = 85, y = 20)

    # 「作成」ボタンの設定
    make_button = ctk.CTkButton(root, text="作成", command=MakeCube)
    make_button.place(x=85, y=60)

    # メイン画面の表示
    root.mainloop()

■実行結果

正常系と異常系について、実行結果を示す。

▼正常系

・ソース実行時の初期画面


・テキストボックスに「100」を入力し、「作成」ボタンを押下する。


・入力した数値に応じて立方体を描画する。

▼異常系

・テキストボックスに「aaa」を入力し、「作成」ボタンを押下する。


・警告メッセージを出力する。

コメント