-
Notifications
You must be signed in to change notification settings - Fork 1.1k
App structure and layout
Unless your program is just a test, you should always structure you're app into classes which inherit from customtkinter.CTk
for the main window and customtinter.CTkToplevel
or customtkinter.CTkFrame
for toplevel windows or frames. By doing so you will get clear and readable code and an expandable app.
The second recommendation is to never use the .place()
geometry manager, but to use .pack()
for very small apps or .grid()
in every other case. The problem with .place()
is that it seems simple at the beginning, when you just place a few widgets on a window. But you block yourself from extending your app. If you want to insert a widget at the top, you have to correct the positions of every other widgets below. With grid
or pack
all the widgets move and align automatically with a given padding and min/max size. By using place
you will never get a consistent padding and a responsive window.
import customtkinter
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.title("minimal example app")
self.minsize(400, 300)
self.button = customtkinter.CTkButton(master=self, command=self.button_callback)
self.button.pack(padx=20, pady=20)
def button_callback(self):
print("button pressed")
if __name__ == "__main__":
app = App()
app.mainloop()
Now we use the grid
geometry manager to create a 2x2 grid system. The first row gets a weight of 1 so it will expand. The second row has a default weight of 0 and will only be as big as it needs to be to fit the widgets inside of it. Both columns get an equal weight of 1 so that they expand equally and fill the window.
The textbook has a column span of 2 so it will fill the first row completely. By setting sticky to nsew
, we force the textbook to stick to all edges of the grid cells it is in. It will expand and completely fill the first row. So set the x-padding to 20 on both sides and the y-padding to (20, 0) so that there is no padding at the bottom. (It will come from the buttons and the entry in the second row)
The entry and button get a padding of 20 on all sides and a sticky of ew
, so that they will expand horizontally and fill the whole grid cell they are in.
import customtkinter
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.geometry("500x300")
self.title("small example app")
self.minsize(300, 200)
# create 2x2 grid system
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure((0, 1), weight=1)
self.textbox = customtkinter.CTkTextbox(master=self)
self.textbox.grid(row=0, column=0, columnspan=2, padx=20, pady=(20, 0), sticky="nsew")
self.combobox = customtkinter.CTkComboBox(master=self, values=["Sample text 1", "Text 2"])
self.combobox.grid(row=1, column=0, padx=20, pady=20, sticky="ew")
self.button = customtkinter.CTkButton(master=self, command=self.button_callback, text="Insert Text")
self.button.grid(row=1, column=1, padx=20, pady=20, sticky="ew")
def button_callback(self):
self.textbox.insert("insert", self.combobox.get() + "\n")
if __name__ == "__main__":
app = App()
app.mainloop()
CustomTkinter by Tom Schimansky 2022
The Github Wiki is outdated, the new documentation can be found at: