PR

CustomTkinterとは?インストールから基本の使い方まで(pip導入・GUI部品の配置)

Python

CUSTOMTKINTER GUIDE

スポンサーリンク

CustomTkinterとは?インストールから基本の使い方まで(pip導入・GUI部品の配置)

こんにちは。ニンジンです🥕

Pythonで簡単なツールを作ったとき、「コマンドプロンプトで動かすのはちょっと不便。ボタンを押すだけで動く画面が欲しい」と思ったことはないでしょうか。標準ライブラリのTkinterでもGUIは作れますが、見た目がどうしても古めかしくなりがちです。

そこで便利なのが、Tkinterを土台にフラットなデザイン・ダークモード対応を実現した「CustomTkinter」というライブラリです。この記事では、CustomTkinterのインストール方法から、Label・Button・Entry・Frameといった基本部品の配置、pack/gridという2つのレイアウト方法までを、実際のコードと画面の描画結果を対応させながら解説します。

この記事で分かること

  • CustomTkinterとは何か、標準Tkinterと何が違うのか
  • CustomTkinterのインストール方法(pip)
  • 最初のウィンドウを表示するための最小構成
  • ライトモード/ダークモードの切り替え方
  • Label・Button・Entry・Frameという基本部品の使い方
  • pack配置とgrid配置の違いと使い分け
スポンサーリンク

こんな人におすすめ

  • Pythonで作った処理に、簡単なGUIをかぶせたい人
  • Tkinterを使ってみたものの、見た目の古さが気になっていた人
  • CustomTkinterという名前は知っているが、何から手をつけていいか分からない人

スポンサーリンク

CustomTkinterとは(標準Tkinterとの違い)

CustomTkinterは、Python標準のGUIライブラリ「Tkinter」をベースに、見た目をモダンなフラットデザインへ拡張したオープンソースのライブラリです。Tkinterの部品(Label・Button・Entryなど)にそれぞれ対応するCTkLabelCTkButtonCTkEntryという部品が用意されていて、書き方はTkinterとほとんど変わりません。

見た目の違いを、同じ「Label + Button」だけの画面で比べてみます。

標準Tkinterで作ったウィンドウ
▲ 標準Tkinterで作ったウィンドウ。ボタンの角が四角く、配色もOS標準のまま
CustomTkinterで作ったウィンドウ
▲ 同じ構成をCustomTkinterで作ったウィンドウ。ボタンが角丸のフラットデザインになる

コードの違いはごくわずかです。

# 標準Tkinter
import tkinter as tk

app = tk.Tk()
label = tk.Label(app, text="標準Tkinterのボタン")
button = tk.Button(app, text="クリック")
# CustomTkinter
import customtkinter as ctk

app = ctk.CTk()
label = ctk.CTkLabel(app, text="CustomTkinterのボタン")
button = ctk.CTkButton(app, text="クリック")

tk.ctk.に、LabelButtonの前にCTkが付くだけで、あとの書き方(pack()で配置する、textで文字を指定するなど)はTkinterと同じ感覚で使えます。Tkinterの経験がある人ほど、スムーズに乗り換えられるはずです。


スポンサーリンク

CustomTkinterのインストール方法(pip)

CustomTkinterはPython標準ライブラリではないため、pipでインストールします。コマンドプロンプト(またはターミナル)で以下を実行してください。

pip install customtkinter
PowerShellでpip install customtkinterを実行した画面
▲ PowerShellで pip install customtkinter を実行したときの画面

インストールが完了すれば、あとはPythonコードの中でimport customtkinterと書くだけで使えるようになります。Tkinter自体はPythonに標準で同梱されているため、別途インストールする必要はありません。


スポンサーリンク

CustomTkinterで最初のウィンドウを表示する(CTk()による最小構成のGUI)

まずは何も部品を置かない、空のウィンドウを表示するだけの最小構成を見てみます。

import customtkinter as ctk

app = ctk.CTk()
app.geometry("400x300")
app.title("CustomTkinter入門")

app.mainloop()
  • ctk.CTk(): アプリのメインウィンドウを作成する
  • geometry("400x300"): ウィンドウの横幅×高さをピクセルで指定する
  • title(...): ウィンドウのタイトルバーに表示する文字列
  • mainloop(): ウィンドウを表示し続け、クリックなどの操作を待ち受ける
ポイント:mainloop()を書き忘れると、ウィンドウが一瞬表示されてすぐ閉じてしまうので注意してください。
部品なしの空のウィンドウ
▲ 上記のコードで表示される、部品なしの空のウィンドウ

スポンサーリンク

CustomTkinterのダークモード/ライトモードを切り替える(set_appearance_mode)

CustomTkinterには、ライトモード/ダークモードを切り替える機能が標準で用意されています。mainloop()より前にset_appearance_mode()を呼び出すだけです。

import customtkinter as ctk

ctk.set_appearance_mode("dark")  # "light" にすると明るい配色になる

app = ctk.CTk()
app.geometry("400x300")
app.title("CustomTkinter入門")

label = ctk.CTkLabel(app, text="ダークモードで表示中")
label.pack(pady=100)

app.mainloop()

"light""dark"のほか、"system"を指定するとOSのモード設定(Windowsの「設定」→「色」で選べるライト/ダーク)に自動で追従します。

ライトモードのウィンドウ
▲ set_appearance_mode(“light”) のときの見た目
ダークモードのウィンドウ
▲ set_appearance_mode(“dark”) のときの見た目。背景色・文字色がまとめて反転する

スポンサーリンク

CustomTkinterの基本GUI部品(Label・Button・Entry・Frame)の使い方

ここからは、CustomTkinterのGUIでよく使う4つの部品(Label・Button・Entry・Frame)を、コードと画面を1つずつ対応させながら見ていきます。

CTkLabelの使い方(テキストを表示する)

CTkLabelは、画面に文字を表示するための部品です。

import customtkinter as ctk

app = ctk.CTk()
app.geometry("400x300")
app.title("CustomTkinter入門")

label = ctk.CTkLabel(app, text="こんにちは、CustomTkinter!")
label.pack(pady=20)

app.mainloop()

pack(pady=20)は「上下に20ピクセルの余白を空けて配置する」という意味です。配置の指定方法については、後述のpack配置で詳しく説明します。

Labelに文字列が表示されたウィンドウ
▲ Labelに指定した文字列がウィンドウ中央付近に表示される

CTkButtonの使い方(クリック操作を受け取る)

CTkButtonは、クリックされたときに任意の処理を実行できる部品です。command引数に、クリック時に呼び出したい関数を渡します。

import customtkinter as ctk

app = ctk.CTk()
app.geometry("400x300")
app.title("CustomTkinter入門")

label = ctk.CTkLabel(app, text="ボタンを押してください")
label.pack(pady=20)

def on_click():
    label.configure(text="クリックされました!")

button = ctk.CTkButton(app, text="クリック", command=on_click)
button.pack(pady=10)

app.mainloop()

ボタンを押すとon_click関数が呼ばれ、label.configure(text=...)でLabelの表示内容がその場で書き換わります。「クリックしたら表示を変える」という、GUIの基本的な仕組みです。

起動直後のボタンとラベル
▲ 起動直後の状態
クリック後にラベルの文字が変わった状態
▲ ボタンをクリックした後。Labelの文字列が書き換わっている

CTkEntryの使い方(入力欄)

CTkEntryはユーザーが文字を入力できる欄です。entry.get()で、入力された文字列をコード側から取得できます。

import customtkinter as ctk

app = ctk.CTk()
app.geometry("400x300")
app.title("CustomTkinter入門")

label = ctk.CTkLabel(app, text="お名前を入力してください")
label.pack(pady=10)

entry = ctk.CTkEntry(app, placeholder_text="山田太郎")
entry.pack(pady=10)

result_label = ctk.CTkLabel(app, text="")
result_label.pack(pady=10)

def on_click():
    name = entry.get()
    result_label.configure(text=f"こんにちは、{name}さん!")

button = ctk.CTkButton(app, text="送信", command=on_click)
button.pack(pady=10)

app.mainloop()

placeholder_textは、未入力のときにグレーで表示される入力例です。ボタンを押すと、entry.get()で取得した文字列を使ってresult_labelの表示を書き換えます。

起動直後の入力欄
▲ 起動直後。入力欄は空でプレースホルダーが表示されている
名前を入力して送信した後の画面
▲ 「たろう」と入力して送信ボタンを押した後

CTkFrameの使い方(部品をグループ化する)

CTkFrameは、複数の部品をひとまとめにする「箱」の役割を持つ部品です。フォーム全体を1つの枠で囲みたいときや、部品をグループごとに分けて配置したいときに使います。

import customtkinter as ctk

app = ctk.CTk()
app.geometry("400x300")
app.title("CustomTkinter入門")

frame = ctk.CTkFrame(app, border_width=2, border_color="#c05208")
frame.pack(padx=20, pady=20, fill="both", expand=True)

label = ctk.CTkLabel(frame, text="お名前を入力してください")
label.pack(pady=10)

entry = ctk.CTkEntry(frame, placeholder_text="山田太郎")
entry.pack(pady=10)

button = ctk.CTkButton(frame, text="送信")
button.pack(pady=10)

app.mainloop()

ポイントは、Label・Entry・Buttonを配置するときの親をappではなくframeにしていることです。こうすることで、これらの部品はFrameの中に収まります。今回は境界を分かりやすくするためにborder_widthborder_colorを指定していますが、枠線なしで単なる余白調整用として使うことも多くあります。

オレンジ色の枠線でグループ化されたフォーム
▲ オレンジ色の枠線がFrameの境界。Label・Entry・ButtonがFrameの中に配置されている

スポンサーリンク

customtkinter pack の使い方:pack配置でレイアウトを組む

ここまでの例でも使ってきたpack()は、部品を「上から下へ」「左から右へ」積み重ねるように配置するレイアウト方法です。複数の部品を横に並べたい場合は、CTkFrameで行ごとにグループ化し、side="left"を指定するのが定番のパターンです。

import customtkinter as ctk

app = ctk.CTk()
app.geometry("400x250")
app.title("CustomTkinter入門(pack)")

row1 = ctk.CTkFrame(app, fg_color="transparent")
row1.pack(pady=10, padx=20, fill="x")
ctk.CTkLabel(row1, text="お名前", width=80, anchor="w").pack(side="left")
ctk.CTkEntry(row1).pack(side="left", fill="x", expand=True)

row2 = ctk.CTkFrame(app, fg_color="transparent")
row2.pack(pady=10, padx=20, fill="x")
ctk.CTkLabel(row2, text="ご年齢", width=80, anchor="w").pack(side="left")
ctk.CTkEntry(row2).pack(side="left", fill="x", expand=True)

ctk.CTkButton(app, text="送信").pack(pady=20)

app.mainloop()
  • side="left": 部品を左詰めで横に並べる
  • fill="x": 横幅いっぱいに広げる
  • expand=True: 余ったスペースをその部品に割り当てる

「お名前」行・「ご年齢」行をそれぞれCTkFrameで1行ずつグループ化し、その中でLabelとEntryを横並びにする、という考え方です。

packで組んだ入力フォーム
▲ packで組んだ2行の入力フォーム

スポンサーリンク

customtkinter grid の使い方:grid配置でレイアウトを組む

grid()は、部品を表計算ソフトのようにマス目(行・列)で位置指定するレイアウト方法です。先ほどのpack版とまったく同じ見た目のフォームを、gridで組み直してみます。

import customtkinter as ctk

app = ctk.CTk()
app.geometry("400x250")
app.title("CustomTkinter入門(grid)")
app.grid_columnconfigure(1, weight=1)

ctk.CTkLabel(app, text="お名前", width=80, anchor="w").grid(row=0, column=0, padx=20, pady=10, sticky="w")
ctk.CTkEntry(app).grid(row=0, column=1, padx=(0, 20), pady=10, sticky="ew")

ctk.CTkLabel(app, text="ご年齢", width=80, anchor="w").grid(row=1, column=0, padx=20, pady=10, sticky="w")
ctk.CTkEntry(app).grid(row=1, column=1, padx=(0, 20), pady=10, sticky="ew")

ctk.CTkButton(app, text="送信").grid(row=2, column=0, columnspan=2, pady=20)

app.mainloop()
  • row= / column=: 配置するマス目の位置(0始まり)
  • sticky="w": マス目の中で部品を左(west)に寄せる。"ew"なら左右いっぱいに広げる
  • columnspan=2: 2列分をまたいで配置する(送信ボタンを中央に置くため)
  • grid_columnconfigure(1, weight=1): 1列目(Entryの列)がウィンドウの余白を優先的に受け取るようにする

pack版では「行ごとにFrameを作ってside="left"で横並びにする」という一手間が必要でしたが、grid版では最初から行・列を指定するだけで同じ配置が作れます。

gridで組んだ入力フォーム
▲ gridで組んだ同じ2行の入力フォーム。pack版とほぼ同じ見た目になる

スポンサーリンク

customtkinter pack と grid、どちらを使うべきか(使い分け)

packgrid
得意な配置上下・左右に部品を積み重ねる、シンプルなレイアウト表形式のフォームなど、行・列がはっきりしたレイアウト
考え方「詰める方向」を指定する「マス目の座標」を指定する
向いているケースボタンを縦に並べるだけ、といった単純な画面項目名+入力欄が複数並ぶ入力フォーム

どちらか一方だけを使う必要はなく、同じウィンドウの中でも「全体の大枠はpack、その中のフォーム部分だけgrid」のように混在させて使うことができます。ただし、同じ親(同じFrameやウィンドウ)の中でpackとgridを混ぜて使うことはできません。「Cannot use geometry manager grid inside .! which already has slaves managed by pack」のようなエラーになるため、親を分けるか、Frameで区切ってから使い分けるようにしてください。


スポンサーリンク

よくある質問

QCustomTkinterとTkinterの違いは何ですか?

ACustomTkinterはTkinterをベースにしたライブラリで、CTkLabelCTkButtonのようにTkinterの部品に対応する部品が用意されています。書き方はほぼ同じですが、見た目がフラットデザインになり、ダークモードにも標準対応している点が大きな違いです。

Qpip installでエラーが出る場合はどうすればいいですか?

Aまずはpip自体が最新かどうかをpython -m pip install --upgrade pipで確認してください。それでも解決しない場合は、Pythonのバージョンが古すぎないか(CustomTkinterはPython 3.9以上を推奨)を確認するのが次のステップです。

Qpackとgridは同じ画面内で混在させてもいいですか?

A同じ親(同じウィンドウやFrame)の中で両方を使うとエラーになります。ただし、親を分ければ問題ありません。たとえば「外側の大枠はpackで組み、その中に置いたFrame1つの中だけgridで組む」といった使い方は可能です。

Qダークモード表示はOSの設定と自動連動しますか?

Aset_appearance_mode("system")を指定した場合のみ、OS側のライト/ダーク設定に自動で追従します。"light"または"dark"を明示的に指定した場合は、OSの設定に関わらずその配色で固定されます。

QCustomTkinterは商用利用できますか?

ACustomTkinterはMITライセンスで公開されているため、商用利用も可能です。ただし最新のライセンス条件は、利用前に公式リポジトリで必ず確認してください。

QTkinterの知識がなくても使えますか?

A使えます。ただし、pack()grid()といった配置の考え方はTkinterと共通のものをそのまま使うため、この記事で紹介した基本部品とレイアウトの使い方を押さえておくと、公式ドキュメントやTkinterの情報を読むときにも役立ちます。


スポンサーリンク

まとめ+実践編への案内

この記事では、CustomTkinterのインストールから、Label・Button・Entry・Frameという基本部品の配置、pack/gridという2つのレイアウト方法までを紹介しました。

  • CustomTkinterはTkinterをベースにした、フラットデザイン・ダークモード対応のGUIライブラリ
  • pip install customtkinterでインストールでき、書き方はTkinterとほぼ同じ
  • Label・Button・Entry・Frameという4つの基本部品を組み合わせるだけで、簡単な入力フォームが作れる
  • pack配置は「詰める方向」、grid配置は「マス目の座標」で部品を並べる

実際にCustomTkinterを使って、もう少し実用的なツール(請求書処理を自動化するツール)にGUIをかぶせた例を、以下の記事で紹介しています。今回学んだLabel・Button・Entryの知識がそのまま活かせる内容になっているので、合わせて読んでみてください。

実践編

【第3回】CustomTkinterでPythonツールをGUI化!ノンプログラマーでも使える汎用アプリの作り方

記事を読む →

ニンジン🥕アイコン

Follow me on X

本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕

@ninjin_py_vba をフォロー

この記事が役に立ったら、シェアしてもらえると嬉しいです🥕

Xでポスト はてブ LINE Pocket

PROJECT LOG — SERIES INDEX
スポンサーリンク

シリーズ記事一覧

電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。

コメント