Skip to main content

1. Create Spinbox

Create widgets from frame​

If you want to create new widgets by yourself, because you need something that's not implemented with Customtkinter, you can easily do this. In the following I created a Spinbox based on float values.

First you create a new class, that inherits from customtkinter.CTkFrame:

import customtkinter

class WidgetName(customtkinter.CTkFrame):
def __init__(self, *args,
width: int = 100,
height: int = 32,
**kwargs):
super().__init__(*args, width=width, height=height, **kwargs)

By doing this, you already have a widget that has a default size given by the default values of the attributes width and height. And it also supports all attributes of a CTkFrame like fg_color and corner_radius.

Create spinbox from frame​

A simple implementation af a float based Spinbox could look like the following:

class FloatSpinbox(customtkinter.CTkFrame):
def __init__(self, *args,
width: int = 100,
height: int = 32,
step_size: Union[int, float] = 1,
command: Callable = None,
**kwargs):
super().__init__(*args, width=width, height=height, **kwargs)

self.step_size = step_size
self.command = command

self.configure(fg_color=("gray78", "gray28")) # set frame color

self.grid_columnconfigure((0, 2), weight=0) # buttons don't expand
self.grid_columnconfigure(1, weight=1) # entry expands

self.subtract_button = customtkinter.CTkButton(self, text="-", width=height-6, height=height-6,
command=self.subtract_button_callback)
self.subtract_button.grid(row=0, column=0, padx=(3, 0), pady=3)

self.entry = customtkinter.CTkEntry(self, width=width-(2*height), height=height-6, border_width=0)
self.entry.grid(row=0, column=1, columnspan=1, padx=3, pady=3, sticky="ew")

self.add_button = customtkinter.CTkButton(self, text="+", width=height-6, height=height-6,
command=self.add_button_callback)
self.add_button.grid(row=0, column=2, padx=(0, 3), pady=3)

# default value
self.entry.insert(0, "0.0")

def add_button_callback(self):
if self.command is not None:
self.command()
try:
value = float(self.entry.get()) + self.step_size
self.entry.delete(0, "end")
self.entry.insert(0, value)
except ValueError:
return

def subtract_button_callback(self):
if self.command is not None:
self.command()
try:
value = float(self.entry.get()) - self.step_size
self.entry.delete(0, "end")
self.entry.insert(0, value)
except ValueError:
return

def get(self) -> Union[float, None]:
try:
return float(self.entry.get())
except ValueError:
return None

def set(self, value: float):
self.entry.delete(0, "end")
self.entry.insert(0, str(float(value)))

Of course you could add a configure method or more attributes to configure the colors in the init method.

But with the above implementation you can use the spin box like the following:

app = customtkinter.CTk()

spinbox_1 = FloatSpinbox(app, width=150, step_size=3)
spinbox_1.pack(padx=20, pady=20)

spinbox_1.set(35)
print(spinbox_1.get())

app.mainloop()
custom made spinbox