Modern, rounded widgets with built-in dark mode โ the easiest way to upgrade tkinter's look.
CustomTkinter is a third-party Python library that wraps and extends standard tkinter with modern, fully custom-drawn widgets. Created by Tom Schimansky, it solves tkinter's biggest weakness โ appearance โ without forcing you to learn a new framework. Under the hood it still uses tkinter's event loop and window management; only the visual layer is replaced.
Widgets are rounded, anti-aliased, and support light mode, dark mode, and system mode (follows OS preference). Color themes (blue, green, dark-blue) can be switched globally with one function call.
CTk replaces Tk() as the root window.CTkButton, CTkEntry, CTkLabel, CTkFrame, CTkScrollableFrame.CTkTabview provides tabbed layouts; CTkOptionMenu and CTkComboBox handle selections.pack(), grid(), or place() โ same rules as tkinter.pip install customtkinter
# Requires tkinter (bundled on Windows/macOS)
python -c "import customtkinter; print(customtkinter.__version__)"
import customtkinter as ctk
ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")
app = ctk.CTk()
app.title("CustomTkinter demo")
app.geometry("360x180")
ctk.CTkLabel(app, text="Modern UI in minutes").pack(pady=16)
ctk.CTkButton(app, text="Click", command=lambda: print("clicked")).pack()
app.mainloop()
import customtkinter as ctk
ctk.set_appearance_mode("system")
app = ctk.CTk()
app.title("Login")
app.geometry("340x220")
frame = ctk.CTkFrame(app)
frame.pack(padx=20, pady=20, fill="both", expand=True)
ctk.CTkLabel(frame, text="Username").grid(row=0, column=0, padx=10, pady=8)
user = ctk.CTkEntry(frame, placeholder_text="Enter username")
user.grid(row=0, column=1, padx=10)
ctk.CTkLabel(frame, text="Password").grid(row=1, column=0, padx=10)
pwd = ctk.CTkEntry(frame, show="*", placeholder_text="Enter password")
pwd.grid(row=1, column=1, padx=10)
def login():
print(user.get(), pwd.get())
ctk.CTkButton(frame, text="Sign in", command=login).grid(row=2, column=1, pady=14, sticky="e")
app.mainloop()
import customtkinter as ctk
app = ctk.CTk()
tabs = ctk.CTkTabview(app)
tabs.pack(padx=20, pady=20, fill="both", expand=True)
tabs.add("General")
tabs.add("Advanced")
ctk.CTkSwitch(tabs.tab("General"), text="Enable notifications").pack(pady=10)
ctk.CTkSlider(tabs.tab("Advanced"), from_=0, to=100).pack(pady=10)
app.mainloop()
set_appearance_mode() and set_default_color_theme() before creating widgets.CTkScrollableFrame for long forms instead of nesting many widgets.CTkImage (not plain PhotoImage) for sharp rendering.customtkinter as a hidden import if auto-detection fails.You want a polished, modern-looking desktop app quickly without learning a heavyweight framework. Pair with standard tkinter for anything CustomTkinter doesn't cover (e.g. complex Treeview tables).
Useful guides and tools (from webpage_links.xlsx).