PythonとCustomTkinterでモダンなデスクトップアプリを作る完全ガイド

Python tutorial - IT technology blog
Python tutorial - IT technology blog

自分のPythonアプリのUIを見て恥ずかしくなったことはありませんか?

以前、チーム向けの社内ツールを作ったことがあります。機能は問題なかったのですが、UIがまるでWindows XP時代のソフトウェアのようでした。灰色のウィンドウ、四角いボタン、極小フォント。同僚に見せたら「これ何で作ったの?Notepadみたいだけど」と言われてしまいました。

そこから、新しいフレームワークを一から学ばなくても、Pythonアプリをちゃんとした見た目にする方法を探し始めました。

従来のTkinterの問題点

TkinterはPythonに標準搭載されているGUIライブラリです。追加インストール不要で、Windows・macOS・Linux上で動作します。しかし最大の欠点は、デフォルトのUIが非常に古臭く見えることです。ウィジェットに角丸はなく、ダークモードもなく、モダンなスタイルとは程遠いものです。

PyQt5やPySide6に乗り換える人も多いですが、それには多くのことを学ぶ必要があります。Qt Designer、シグナル/スロット、そしてPyQt5のライセンス問題は商用プロジェクトではかなり頭が痛いです。

wxPythonはどうでしょう?同様に入門ハードルが高く、ドキュメントが少なく、コミュニティも小さいです。

ではシンプルな社内ツールをまともな見た目で作りたいだけなら、もっと手軽な方法はないのでしょうか?

CustomTkinter — 2024年向けに作り直されたTkinter

CustomTkinterはTom Schimanskyが開発したPythonライブラリです。本質的にはTkinterをラップし、全ウィジェットを独自に描き直したものに置き換えています。角丸、モダンな配色、OSに合わせた自動ダーク/ライトモード切替に対応しています。

最大の利点は、Tkinterを知っていればほぼ学習不要という点です。構文はほぼ同じで、ウィジェット名にctkプレフィックスを付けるだけです。

インストール

pip install customtkinter

重い依存関係はありません。Qtも、C++コンパイラも不要です。

初めてのアプリを作る — ステップバイステップ

実用的な例として、温度変換ツール(Celsius ↔ Fahrenheit)を作ってみましょう。小さなアプリですが、CustomTkinterの動作を理解するには十分です。

基本的な骨組み

import customtkinter as ctk

# デフォルトの外観を設定
ctk.set_appearance_mode("System")   # OSに合わせる: Light/Dark
ctk.set_default_color_theme("blue") # テーマカラー: blue, green, dark-blue

app = ctk.CTk()                     # メインウィンドウ(tk.Tk()の代わり)
app.title("温度変換")
app.geometry("400x300")

app.mainloop()

実行すると、角丸のきれいなウィンドウがすぐに表示されます。macOSアプリのような見た目で、最初の行から違いがはっきりわかります。

ウィジェットとロジックの追加

import customtkinter as ctk

ctk.set_appearance_mode("System")
ctk.set_default_color_theme("blue")

def convert():
    try:
        celsius = float(entry_celsius.get())
        fahrenheit = celsius * 9 / 5 + 32
        label_result.configure(text=f"{fahrenheit:.1f} °F")
    except ValueError:
        label_result.configure(text="有効な数値を入力してください!")

app = ctk.CTk()
app.title("温度変換")
app.geometry("400x280")
app.resizable(False, False)

# タイトル
ctk.CTkLabel(app, text="温度変換",
             font=ctk.CTkFont(size=20, weight="bold")).pack(pady=20)

# 入力フィールド
entry_celsius = ctk.CTkEntry(app, placeholder_text="摂氏を入力...", width=200)
entry_celsius.pack(pady=10)

# ボタン
ctk.CTkButton(app, text="°Fに変換", command=convert, width=200).pack(pady=10)

# 結果表示
label_result = ctk.CTkLabel(app, text="", font=ctk.CTkFont(size=18))
label_result.pack(pady=10)

# ダーク/ライトモード切替
def toggle_mode():
    current = ctk.get_appearance_mode()
    ctk.set_appearance_mode("Light" if current == "Dark" else "Dark")

ctk.CTkButton(app, text="ダーク/ライト切替", command=toggle_mode,
              fg_color="gray40", hover_color="gray30", width=140).pack(pady=5)

app.mainloop()

35行未満のコードで、ダークモード切替付きのきれいなアプリが完成します。見せかけのダークモードではありません。CustomTkinterはウィジェットを完全に描き直しているので、本物のダーク背景です。

よく使うウィジェット

CustomTkinterには一般的なウィジェットが揃っています。社内ツールでよく使うものをまとめました:

  • CTkEntry — 入力フィールド、プレースホルダーテキスト対応
  • CTkButton — ボタン、fg_colorhover_colorでカスタマイズ可能
  • CTkLabel — テキストラベル、カスタムフォント対応
  • CTkFrame — ウィジェットのコンテナ、レイアウトのグループ化に使用
  • CTkTextbox — 複数行テキストエディタ(Textの代替)
  • CTkComboBox — 値選択ドロップダウン
  • CTkSwitch — iOSスタイルのトグルスイッチ
  • CTkProgressBar — プログレスバー
  • CTkScrollableFrame — スクロール対応フレーム、長いリストに便利
  • CTkTabview — タブレイアウト、画面を複数タブに分割

複数タブを使った実践的なレイアウト

もう少し複雑なアプリの場合、すべてを1画面に詰め込む代わりにCTkTabviewでコンテンツを分割するのが便利です:

import customtkinter as ctk

app = ctk.CTk()
app.geometry("500x350")
app.title("社内ツール")

tabview = ctk.CTkTabview(app, width=480, height=320)
tabview.pack(padx=10, pady=10)

tabview.add("ファイル処理")
tabview.add("設定")
tabview.add("ログ")

# タブ1のコンテンツ
ctk.CTkLabel(tabview.tab("ファイル処理"),
             text="ここにファイルをドロップ...").pack(pady=40)

# タブ3のコンテンツ — ログ表示用テキストボックス
log_box = ctk.CTkTextbox(tabview.tab("ログ"), width=440, height=200)
log_box.pack(padx=10, pady=10)
log_box.insert("end", "[INFO] アプリ起動...\n")

app.mainloop()

テキスト処理ツールを作る際の小技

ログ処理ツールを作っていたとき、Pythonコードに組み込む前に正規表現パターンを検証する必要がありました。スクリプトを何度も実行する代わりに、toolcraft.app/ja/tools/developer/regex-testerで素早くテストしていました。ブラウザ上でそのまま動作し、インストール不要で結果がリアルタイムに表示されます。パターンが確認できてからCustomTkinterのコードに貼り付けるので、デバッグ時間をかなり節約できました。

.exeファイルにパッケージして配布する

アプリが完成したら、同僚にPythonをインストールさせずに使ってもらいたいですか?PyInstallerを使いましょう:

# PyInstallerをインストール
pip install pyinstaller

# 1つの.exeファイルにパッケージ化(Windows)
pyinstaller --onefile --windowed --name "AppName" main.py

# 出力はdist/フォルダに生成される
# dist/AppName.exe

--windowedフラグで実行時にターミナルウィンドウを非表示にします(GUIウィンドウのみ表示)。--onefileですべてを1ファイルにまとめ、配布しやすくなります。

事前に知っておくべきこと:CustomTkinterを含めてパッケージ化した.exeファイルは通常30〜50MBほどになります。小さなアプリにしてはやや大きいですが、社内ツールであれば誰も気にしません。

CustomTkinterは大規模プロジェクトに向いていますか?

正直に言うと、必ずしもそうではありません。複雑なデスクトップアプリ — 多数のサブウィンドウ、高度なドラッグ&ドロップ、OpenGL、モバイル向けビルドが必要な場合は、PyQt/PySide6やKivyの方が適しています。

しかし、以下のような場合には:

  • チーム向けの社内ツール(1〜10人のユーザー)
  • コマンドラインの代わりにGUI付きの自動化スクリプト
  • デモ用の素早いプロトタイプ
  • 小さいけどきちんとした見た目のアプリ

…CustomTkinterが最良の選択肢です。習得が早く、コード量が少なく、仕上がりがきれいです。

まとめ

CustomTkinterはTkinterが長らく放置してきた問題を正確に解決しています。古臭いUIです。欲張りではなく、ただ一つのことをうまくやります。そしてTkinterを知っていれば、ほぼ学び直しは不要です。

次に社内ツールを作るときは、コマンドラインスクリプトを作ってチーム全員に使い方を説明する代わりに、CustomTkinterで1〜2時間かけてGUIを作ってみてください。同僚からの疑わしい目線はきっとなくなるはずです。

Share: