CUSTOMTKINTER GUIDE
- CustomTkinterとは?インストールから基本の使い方まで(pip導入・GUI部品の配置)
- こんな人におすすめ
- CustomTkinterとは(標準Tkinterとの違い)
- CustomTkinterのインストール方法(pip)
- CustomTkinterで最初のウィンドウを表示する(CTk()による最小構成のGUI)
- CustomTkinterのダークモード/ライトモードを切り替える(set_appearance_mode)
- CustomTkinterの基本GUI部品(Label・Button・Entry・Frame)の使い方
- customtkinter pack の使い方:pack配置でレイアウトを組む
- customtkinter grid の使い方:grid配置でレイアウトを組む
- customtkinter pack と grid、どちらを使うべきか(使い分け)
- よくある質問
- まとめ+実践編への案内
- シリーズ記事一覧
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など)にそれぞれ対応するCTkLabel・CTkButton・CTkEntryという部品が用意されていて、書き方はTkinterとほとんど変わりません。
見た目の違いを、同じ「Label + Button」だけの画面で比べてみます。
コードの違いはごくわずかです。
# 標準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.に、Label・Buttonの前にCTkが付くだけで、あとの書き方(pack()で配置する、textで文字を指定するなど)はTkinterと同じ感覚で使えます。Tkinterの経験がある人ほど、スムーズに乗り換えられるはずです。
CustomTkinterのインストール方法(pip)
CustomTkinterはPython標準ライブラリではないため、pipでインストールします。コマンドプロンプト(またはターミナル)で以下を実行してください。
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の「設定」→「色」で選べるライト/ダーク)に自動で追従します。
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配置で詳しく説明します。
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の基本的な仕組みです。
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_widthとborder_colorを指定していますが、枠線なしで単なる余白調整用として使うことも多くあります。
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を横並びにする、という考え方です。
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版では最初から行・列を指定するだけで同じ配置が作れます。
customtkinter pack と grid、どちらを使うべきか(使い分け)
| pack | grid | |
|---|---|---|
| 得意な配置 | 上下・左右に部品を積み重ねる、シンプルなレイアウト | 表形式のフォームなど、行・列がはっきりしたレイアウト |
| 考え方 | 「詰める方向」を指定する | 「マス目の座標」を指定する |
| 向いているケース | ボタンを縦に並べるだけ、といった単純な画面 | 項目名+入力欄が複数並ぶ入力フォーム |
どちらか一方だけを使う必要はなく、同じウィンドウの中でも「全体の大枠はpack、その中のフォーム部分だけgrid」のように混在させて使うことができます。ただし、同じ親(同じFrameやウィンドウ)の中でpackとgridを混ぜて使うことはできません。「Cannot use geometry manager grid inside .! which already has slaves managed by pack」のようなエラーになるため、親を分けるか、Frameで区切ってから使い分けるようにしてください。
よくある質問
QCustomTkinterとTkinterの違いは何ですか?
ACustomTkinterはTkinterをベースにしたライブラリで、CTkLabelやCTkButtonのように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の知識がそのまま活かせる内容になっているので、合わせて読んでみてください。
Follow me on X
本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕
@ninjin_py_vba をフォローシリーズ記事一覧
電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。
-
FILE.01 — IoT
Raspberry Pi Pico W × GASラズパイPico W×GASで自作!「LINEで動く温湿度&スマートリモコン」完全ロードマップ
「外出中のペットの室温が心配…」そんな思いからスタートしたIoT自作プロジェクトの総集編。温湿度監視からエアコン遠隔操作まで、仕組みをゼロから作りたい方のための全5回の開発記録です。
シリーズを読む -
FILE.02 — CNC
Arduino × レーザー刻印CNCCNC自作シリーズ
高精度な加工を目指し、本格的な自作CNC製作に挑戦中。現在は基幹パーツであるオリエンタルモーターの納品を待つ「設計・準備編」を公開。ハードとソフトの両面から、理想のマシンを形にする過程をリアルタイムにお届けします。
シリーズを読む -
FILE.03 — XY軸制御
Raspberry Pi × ステッピングモーターXYテーブルシリーズ
Raspberry Piとステッパモーターを使い、ゼロから2軸制御に挑む記録。OS設定から回路設計、多軸制御のPythonコードまで、躓きやすいポイントを徹底図解。電子工作初心者が「動く感動」を味わうための実戦ガイドです。
シリーズを読む -
FILE.04 — 業務自動化
Python × Excel × CustomTkinter【Python開発記】NINJIN Mail制作記
PythonとExcelを連携させ、実務で即戦力となるメール送信ツールを開発。CustomTkinterによるUI構築や、ミスを防ぐテンプレート活用術など、現場の「痒い所に手が届く」自動化ノウハウを細部まで丁寧に解説します。
シリーズを読む -
FILE.05 — 業務自動化
Python × Excel × GUIアプリ化Invoice Maker(請求書・見積書自動作成)
手作業の請求書作成から卒業!PythonでExcelデータを読み込み一括PDF化する「Invoice_Maker」の作り方を全3回で解説。基本ロジックからGUIアプリ化まで、実務で役立つ自動化ノウハウが満載です。
シリーズを読む -
FILE.06 — 業務自動化
Access × VBA【Access VBA開発記】対応履歴管理データベース
問い合わせ・トラブル対応履歴がExcelでバラバラに散らばる悩みから、Access+VBAで検索性の高い管理データベースを自作。テンプレート配布から設計解説、Win32 API実装で味わった失敗談まで、生成AI時代の検証記録を全3回でお届けします。
シリーズを読む



コメント