add font rendering to button, finished

This commit is contained in:
TomSchimansky 2022-02-22 22:38:40 +01:00
parent 5bbcb1c617
commit 9996e51c1a
22 changed files with 348 additions and 306 deletions

View File

@ -195,6 +195,18 @@ root_tk.configure(bg_color=(<light-mode color>, <dark-mode color>))
```
</details>
### CTkToplevel
CTkToplevel works exactly like the `Tkinter.Toplevel`, and should be used to create more than one window.
<details>
<summary>Show all arguments and methods:</summary>
argument | value
--- | ---
bg_color or bg | tuple: (light_color, dark_color) or single color
</details>
### CTkFrame
Example Code:
```python
@ -376,6 +388,7 @@ text_color | text color, tuple: (light_color, dark_color) or single color
text_font | button text font, tuple: (font_name, size)
hover | enable/disable hover effect: True, False
state | tkinter.NORMAL (standard) or tkinter.DISABLED (not clickable, darker color)
command | function will be called when the checkbox is clicked
CTkCheckBox Methods:
```python

View File

@ -13,7 +13,7 @@ from .customtkinter_canvas import CTkCanvas
from .customtkinter_toplevel import CTkToplevel
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
from distutils.version import StrictVersion as Version
import tkinter
@ -58,7 +58,7 @@ def get_appearance_mode():
def set_default_color_theme(color_string):
CTkColorManager.initialize_color_theme(color_string)
CTkThemeManager.initialize_color_theme(color_string)
def load_font_windows(fontpath: str, private=True, enumerable=False):

View File

@ -1,4 +1,3 @@
import time
import sys
import tkinter
from distutils.version import StrictVersion as Version
@ -28,15 +27,6 @@ class AppearanceModeTracker:
cls.appearance_mode = new_appearance_mode
cls.update_callbacks()
@classmethod
def get_tk_root_of_widget(cls, widget):
current_widget = widget
while isinstance(current_widget, tkinter.Tk) is False:
current_widget = current_widget.master
return current_widget
@classmethod
def add(cls, callback, widget=None):
cls.callback_list.append(callback)
@ -50,6 +40,10 @@ class AppearanceModeTracker:
root_tk.after(500, cls.update)
cls.update_loop_running = True
@classmethod
def remove(cls, callback):
cls.callback_list.remove(callback)
@staticmethod
def detect_appearance_mode():
try:
@ -60,6 +54,15 @@ class AppearanceModeTracker:
except NameError:
return 0 # Light
@classmethod
def get_tk_root_of_widget(cls, widget):
current_widget = widget
while isinstance(current_widget, tkinter.Tk) is False:
current_widget = current_widget.master
return current_widget
@classmethod
def update_callbacks(cls):
if cls.appearance_mode == 0:
@ -95,10 +98,6 @@ class AppearanceModeTracker:
cls.update_loop_running = False
@classmethod
def remove(cls, callback):
cls.callback_list.remove(callback)
@classmethod
def get_mode(cls):
return cls.appearance_mode

View File

@ -4,8 +4,9 @@ import sys
from .customtkinter_tk import CTk
from .customtkinter_frame import CTkFrame
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
from .customtkinter_canvas import CTkCanvas
from .customtkinter_settings import CTkSettings
class CTkButton(tkinter.Frame):
@ -13,9 +14,9 @@ class CTkButton(tkinter.Frame):
def __init__(self, *args,
bg_color=None,
fg_color="CTkColorManager",
hover_color="CTkColorManager",
border_color="CTkColorManager",
fg_color="default_theme",
hover_color="default_theme",
border_color="default_theme",
border_width=0,
command=None,
textvariable=None,
@ -23,7 +24,7 @@ class CTkButton(tkinter.Frame):
height=30,
corner_radius=8,
text_font=None,
text_color="CTkColorManager",
text_color="default_theme",
text="CTkButton",
hover=True,
image=None,
@ -60,9 +61,9 @@ class CTkButton(tkinter.Frame):
# color variables
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
self.fg_color = CTkColorManager.MAIN if fg_color == "CTkColorManager" else fg_color
self.hover_color = CTkColorManager.MAIN_HOVER if hover_color == "CTkColorManager" else hover_color
self.border_color = CTkColorManager.CHECKBOX_LINES if border_color == "CTkColorManager" else border_color
self.fg_color = CTkThemeManager.MAIN_COLOR if fg_color == "default_theme" else fg_color
self.hover_color = CTkThemeManager.MAIN_HOVER_COLOR if hover_color == "default_theme" else hover_color
self.border_color = CTkThemeManager.CHECKBOX_LINES_COLOR if border_color == "default_theme" else border_color
# shape and size
self.width = width
@ -86,12 +87,12 @@ class CTkButton(tkinter.Frame):
self.image_label = None
self.text = text
self.text_label = None
self.text_color = CTkColorManager.TEXT if text_color == "CTkColorManager" else text_color
self.text_color = CTkThemeManager.TEXT_COLOR if text_color == "default_theme" else text_color
if text_font is None:
if sys.platform == "darwin": # macOS
self.text_font = ("Avenir", 13)
elif "win" in sys.platform: # Windows
self.text_font = ("Century Gothic", 11)
elif sys.platform.startswith("win"): # Windows
self.text_font = ("Segoe UI", -14)
else:
self.text_font = "TkDefaultFont"
else:
@ -169,52 +170,53 @@ class CTkButton(tkinter.Frame):
return user_corner_radius + 0.5
else:
return user_corner_radius
elif draw_method == "font":
return round(user_corner_radius)
def draw(self, no_color_updates=False):
self.canvas.configure(bg=CTkColorManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
# decide the drawing method
if sys.platform == "darwin":
# on macOS draw button with polygons (positions are more accurate, macOS has Antialiasing)
self.draw_with_polygon_shapes()
elif sys.platform.startswith("win"):
#self.draw_with_ovals_and_rects()
self.draw_with_font_shapes_and_rects()
# self.draw_with_ovals_and_rects()
draw_color_update = self.draw_with_font_shapes_and_rects()
else:
# on Windows and other draw with ovals (corner_radius can be optimised to look better than with polygons)
# on other draw with ovals (corner_radius can be optimised to look better than with polygons)
self.draw_with_ovals_and_rects()
if no_color_updates is False:
if no_color_updates is False or draw_color_update:
# set color for the button border parts (outline)
self.canvas.itemconfig("border_parts",
outline=CTkColorManager.single_color(self.border_color, self.appearance_mode),
fill=CTkColorManager.single_color(self.border_color, self.appearance_mode))
outline=CTkThemeManager.single_color(self.border_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
# set color for inner button parts (depends on button state)
if self.state == tkinter.DISABLED:
if self.fg_color is None:
self.canvas.itemconfig("inner_parts",
outline=CTkColorManager.darken_hex_color(CTkColorManager.single_color(self.bg_color, self.appearance_mode)),
fill=CTkColorManager.darken_hex_color(CTkColorManager.single_color(self.bg_color, self.appearance_mode)))
outline=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.bg_color, self.appearance_mode)),
fill=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.bg_color, self.appearance_mode)))
else:
self.canvas.itemconfig("inner_parts",
outline=CTkColorManager.darken_hex_color(
CTkColorManager.single_color(self.fg_color, self.appearance_mode)),
fill=CTkColorManager.darken_hex_color(
CTkColorManager.single_color(self.fg_color, self.appearance_mode)))
outline=CTkThemeManager.darken_hex_color(
CTkThemeManager.single_color(self.fg_color, self.appearance_mode)),
fill=CTkThemeManager.darken_hex_color(
CTkThemeManager.single_color(self.fg_color, self.appearance_mode)))
else:
if self.fg_color is None:
self.canvas.itemconfig("inner_parts",
outline=CTkColorManager.single_color(self.bg_color, self.appearance_mode),
fill=CTkColorManager.single_color(self.bg_color, self.appearance_mode))
outline=CTkThemeManager.single_color(self.bg_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
else:
self.canvas.itemconfig("inner_parts",
outline=CTkColorManager.single_color(self.fg_color, self.appearance_mode),
fill=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
outline=CTkThemeManager.single_color(self.fg_color, self.appearance_mode),
fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
# create text label if text given
if self.text is not None and self.text != "":
@ -229,21 +231,21 @@ class CTkButton(tkinter.Frame):
if no_color_updates is False:
# set text_label fg color (text color)
self.text_label.configure(fg=CTkColorManager.single_color(self.text_color, self.appearance_mode))
self.text_label.configure(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
# set text_label bg color (label color)
if self.state == tkinter.DISABLED:
if self.fg_color is None:
self.text_label.configure(
bg=CTkColorManager.darken_hex_color(CTkColorManager.single_color(self.bg_color, self.appearance_mode)))
bg=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.bg_color, self.appearance_mode)))
else:
self.text_label.configure(
bg=CTkColorManager.darken_hex_color(CTkColorManager.single_color(self.fg_color, self.appearance_mode)))
bg=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.fg_color, self.appearance_mode)))
else:
if self.fg_color is None:
self.text_label.configure(bg=CTkColorManager.single_color(self.bg_color, self.appearance_mode))
self.text_label.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
else:
self.text_label.configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
self.text_label.configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.text_label.configure(text=self.text) # set text
@ -267,9 +269,9 @@ class CTkButton(tkinter.Frame):
if no_color_updates is False:
# set image_label bg color (background color of label)
if self.state == tkinter.DISABLED:
self.image_label.configure(bg=CTkColorManager.darken_hex_color(CTkColorManager.single_color(self.fg_color, self.appearance_mode)))
self.image_label.configure(bg=CTkThemeManager.darken_hex_color(CTkThemeManager.single_color(self.fg_color, self.appearance_mode)))
else:
self.image_label.configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
self.image_label.configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.image_label.configure(image=self.image) # set image
@ -447,6 +449,7 @@ class CTkButton(tkinter.Frame):
self.height - self.inner_corner_radius - self.border_width + rect_bottom_right_shift))
def draw_with_font_shapes_and_rects(self):
draw_color_update = False
# create border button parts
if self.border_width > 0:
@ -457,10 +460,16 @@ class CTkButton(tkinter.Frame):
self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_1_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180)
self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_2_a", "border_corner_part", "border_parts"), anchor=tkinter.CENTER)
self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_2_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180)
if not self.canvas.find_withtag("border_oval_3_a") and round(self.corner_radius) * 2 < self.height:
self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_3_a", "border_corner_part", "border_parts"), anchor=tkinter.CENTER)
self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_3_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180)
self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_4_a", "border_corner_part", "border_parts"), anchor=tkinter.CENTER)
self.canvas.create_aa_circle(0, 0, 0, tags=("border_oval_4_b", "border_corner_part", "border_parts"), anchor=tkinter.CENTER, angle=180)
draw_color_update = True
self.canvas.tag_lower("border_parts")
elif self.canvas.find_withtag("border_oval_3_a") and not round(self.corner_radius) * 2 < self.height:
self.canvas.delete(["border_oval_3_a", "border_oval_3_b", "border_oval_4_a", "border_oval_4_b"])
# change position of border corner parts
self.canvas.coords("border_oval_1_a", self.corner_radius, self.corner_radius, self.corner_radius)
@ -481,30 +490,29 @@ class CTkButton(tkinter.Frame):
self.canvas.create_rectangle(0, 0, 0, 0, tags=("border_rectangle_2", "border_rectangle_part", "border_parts"))
# change position of border rectangle parts
self.canvas.coords("border_rectangle_1", (0,
self.corner_radius,
self.width -1,
self.height - self.corner_radius -1))
self.canvas.coords("border_rectangle_2", (self.corner_radius,
0,
self.width - self.corner_radius -1,
self.height -1))
self.canvas.coords("border_rectangle_1", (0, self.corner_radius, self.width -1, self.height - self.corner_radius -1))
self.canvas.coords("border_rectangle_2", (self.corner_radius, 0, self.width - self.corner_radius -1, self.height -1))
# create inner button parts
if self.inner_corner_radius > 0:
# create canvas border corner parts if not already created
if not self.canvas.find_withtag("inner_corner_part"):
if not self.canvas.find_withtag("inner_oval_1_a"):
self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_1_a", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER)
self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_1_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180)
self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_2_a", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER)
self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_2_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180)
if not self.canvas.find_withtag("inner_oval_3_a") and round(self.inner_corner_radius) * 2 < self.height - (2 * self.border_width):
self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_3_a", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER)
self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_3_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180)
self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_4_a", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER)
self.canvas.create_aa_circle(0, 0, 0, tags=("inner_oval_4_b", "inner_corner_part", "inner_parts"), anchor=tkinter.CENTER, angle=180)
self.canvas.tag_raise("inner_parts")
draw_color_update = True
elif self.canvas.find_withtag("inner_oval_3_a") and not round(self.inner_corner_radius) * 2 < self.height - (2 * self.border_width):
self.canvas.delete(["inner_oval_3_a", "inner_oval_3_b", "inner_oval_4_a", "inner_oval_4_b"])
#print(self.corner_radius, self.border_width, self.inner_corner_radius)
# change position of border corner parts
self.canvas.coords("inner_oval_1_a", self.border_width + self.inner_corner_radius, self.border_width + self.inner_corner_radius, self.inner_corner_radius)
self.canvas.coords("inner_oval_1_b", self.border_width + self.inner_corner_radius, self.border_width + self.inner_corner_radius, self.inner_corner_radius)
@ -518,9 +526,15 @@ class CTkButton(tkinter.Frame):
self.canvas.delete("inner_corner_part") # delete inner corner parts if not needed
# create canvas inner rectangle parts if not already created
if not self.canvas.find_withtag("inner_rectangle_part"):
if not self.canvas.find_withtag("inner_rectangle_1"):
self.canvas.create_rectangle(0, 0, 0, 0, tags=("inner_rectangle_1", "inner_rectangle_part", "inner_parts"))
if not self.canvas.find_withtag("inner_rectangle_2") and self.inner_corner_radius * 2 < self.height - (self.border_width * 2):
self.canvas.create_rectangle(0, 0, 0, 0, tags=("inner_rectangle_2", "inner_rectangle_part", "inner_parts"))
self.canvas.tag_raise("inner_parts")
draw_color_update = True
elif self.canvas.find_withtag("inner_rectangle_2") and not self.inner_corner_radius * 2 < self.height - (self.border_width * 2):
self.canvas.delete("inner_rectangle_2")
# change position of inner rectangle parts
self.canvas.coords("inner_rectangle_1", (self.border_width + self.inner_corner_radius,
@ -532,6 +546,8 @@ class CTkButton(tkinter.Frame):
self.width - self.border_width -1,
self.height - self.inner_corner_radius - self.border_width -1))
return draw_color_update
def config(self, *args, **kwargs):
self.configure(*args, **kwargs)
@ -630,16 +646,16 @@ class CTkButton(tkinter.Frame):
# set color of inner button parts to hover color
self.canvas.itemconfig("inner_parts",
outline=CTkColorManager.single_color(inner_parts_color, self.appearance_mode),
fill=CTkColorManager.single_color(inner_parts_color, self.appearance_mode))
outline=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode),
fill=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
# set text_label bg color to button hover color
if self.text_label is not None:
self.text_label.configure(bg=CTkColorManager.single_color(inner_parts_color, self.appearance_mode))
self.text_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
# set image_label bg color to button hover color
if self.image_label is not None:
self.image_label.configure(bg=CTkColorManager.single_color(inner_parts_color, self.appearance_mode))
self.image_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
def on_leave(self, event=0):
self.click_animation_running = False
@ -652,16 +668,16 @@ class CTkButton(tkinter.Frame):
# set color of inner button parts
self.canvas.itemconfig("inner_parts",
outline=CTkColorManager.single_color(inner_parts_color, self.appearance_mode),
fill=CTkColorManager.single_color(inner_parts_color, self.appearance_mode))
outline=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode),
fill=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
# set text_label bg color (label color)
if self.text_label is not None:
self.text_label.configure(bg=CTkColorManager.single_color(inner_parts_color, self.appearance_mode))
self.text_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
# set image_label bg color (image bg color)
if self.image_label is not None:
self.image_label.configure(bg=CTkColorManager.single_color(inner_parts_color, self.appearance_mode))
self.image_label.configure(bg=CTkThemeManager.single_color(inner_parts_color, self.appearance_mode))
def click_animation(self):
if self.click_animation_running:

View File

@ -1,23 +1,23 @@
import tkinter
from .customtkinter_settings import CTkSettings
class CTkCanvas(tkinter.Canvas):
radius_to_char = {19: 'B', 18: 'B', 17: 'B', 16: 'B', 15: 'B', 14: 'B', 13: 'B', 12: 'B', 11: 'B', 10: 'B',
9: 'C', 8: 'D', 7: 'C', 6: 'E', 5: 'F', 4: 'F', 3: 'H', 2: 'H', 1: 'H', 0: 'A'}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.aa_circle_canvas_ids = []
def get_char_from_radius(self, radius):
if radius >= 10:
char = "B"
elif radius >= 6:
char = "D"
elif radius >= 3:
char = "H"
else:
char = "H"
return char
if CTkSettings.scaling_factor == 1:
if radius >= 20:
return "A"
else:
return self.radius_to_char[radius]
def create_aa_circle(self, x_pos, y_pos, radius, angle=0, fill="white", tags="", anchor=tkinter.CENTER) -> str:
# create a circle with a font element

View File

@ -4,7 +4,7 @@ import sys
from .customtkinter_tk import CTk
from .customtkinter_frame import CTkFrame
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
class CTkCheckBox(tkinter.Frame):
@ -12,15 +12,15 @@ class CTkCheckBox(tkinter.Frame):
def __init__(self, *args,
bg_color=None,
fg_color="CTkColorManager",
hover_color="CTkColorManager",
border_color="CTkColorManager",
fg_color="default_theme",
hover_color="default_theme",
border_color="default_theme",
border_width=3,
width=25,
height=25,
corner_radius=4,
text_font=None,
text_color="CTkColorManager",
text_color="default_theme",
text="CTkCheckBox",
hover=True,
command=None,
@ -57,9 +57,9 @@ class CTkCheckBox(tkinter.Frame):
self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
self.fg_color = CTkColorManager.MAIN if fg_color == "CTkColorManager" else fg_color
self.hover_color = CTkColorManager.MAIN_HOVER if hover_color == "CTkColorManager" else hover_color
self.border_color = CTkColorManager.CHECKBOX_LINES if border_color == "CTkColorManager" else border_color
self.fg_color = CTkThemeManager.MAIN_COLOR if fg_color == "default_theme" else fg_color
self.hover_color = CTkThemeManager.MAIN_HOVER_COLOR if hover_color == "default_theme" else hover_color
self.border_color = CTkThemeManager.CHECKBOX_LINES_COLOR if border_color == "default_theme" else border_color
self.width = width
self.height = height
@ -78,7 +78,7 @@ class CTkCheckBox(tkinter.Frame):
self.inner_corner_radius = 0
self.text = text
self.text_color = CTkColorManager.TEXT if text_color == "CTkColorManager" else text_color
self.text_color = CTkThemeManager.TEXT_COLOR if text_color == "default_theme" else text_color
if text_font is None:
if sys.platform == "darwin": # macOS
self.text_font = ("Avenir", 13)

View File

@ -1,129 +0,0 @@
import sys
class CTkColorManager:
WINDOW_BG = None
MAIN = None
MAIN_HOVER = None
ENTRY = None
TEXT = None
PLACEHOLDER_TEXT = None
LABEL_BG = None
SLIDER_BG = None
SLIDER_PROGRESS = None
PROGRESS_BG = None
FRAME = None
FRAME_2 = None
CHECKBOX_LINES = None
DARKEN_COLOR_FACTOR = None
@classmethod
def initialize_color_theme(cls, theme_name):
if theme_name.lower() == "blue":
cls.WINDOW_BG = ("#ECECEC", "#323232") # macOS standard light and dark window bg colors
cls.MAIN = ("#64A1D2", "#1C94CF")
cls.MAIN_HOVER = ("#A7C2E0", "#5FB4DD")
cls.ENTRY = ("white", "#222222")
cls.TEXT = ("black", "white")
cls.PLACEHOLDER_TEXT = ("gray52", "gray62")
cls.LABEL_BG = ("white", "#626061")
cls.SLIDER_BG = ("#6B6B6B", "#222222")
cls.SLIDER_PROGRESS = ("#A5A6A5", "#555555")
cls.PROGRESS_BG = ("#6B6B6B", "#222222")
cls.FRAME = ("#D4D5D6", "#3F3F3F")
cls.FRAME_2 = ("#BFBEC1", "#505050")
cls.CHECKBOX_LINES = ("black", "#ededed")
cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button
elif theme_name.lower() == "green":
cls.WINDOW_BG = ("#ECECEC", "#323232") # macOS standard light and dark window bg colors
cls.MAIN = ("#13C995", "#1ABE87")
cls.MAIN_HOVER = ("#6ACBA5", "#81E4B2")
cls.ENTRY = ("gray60", "#222223")
cls.TEXT = ("gray25", "gray92")
cls.PLACEHOLDER_TEXT = ("gray32", "gray55")
cls.LABEL_BG = ("white", "#626061")
cls.SLIDER_BG = ("#636363", "#0D1321")
cls.SLIDER_PROGRESS = ("white", "#727578")
cls.PROGRESS_BG = ("#636363", "#0D1321")
cls.FRAME = ("#D4D5D6", "#3F3F3F")
cls.FRAME_2 = ("#BFBEC1", "#505050")
cls.CHECKBOX_LINES = ("#414141", "#EDEDED")
cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button
elif theme_name.lower() == "dark-blue":
cls.WINDOW_BG = ("#F1F1F1", "#192026") # macOS standard light and dark window bg colors
cls.MAIN = ("#608BD5", "#395E9C")
cls.MAIN_HOVER = ("#A4BDE6", "#748BB3")
cls.ENTRY = ("#FCFCFC", "#111116")
cls.TEXT = ("black", "white")
cls.PLACEHOLDER_TEXT = ("gray52", "gray62")
cls.LABEL_BG = ("white", "#444444")
cls.SLIDER_BG = ("#444444", "#444444")
cls.SLIDER_PROGRESS = ("white", "#AAAAAA")
cls.PROGRESS_BG = ("#636363", "#0D1321")
cls.FRAME = ("#DADADA", "#2B2C2E")
cls.FRAME_2 = ("#C4C4C4", "#383838")
cls.CHECKBOX_LINES = ("#313131", "white")
cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button
@staticmethod
def single_color(color, appearance_mode: int) -> str:
""" color can be either a single hex color string or a color name or it can be a
tuple color with (light_color, dark_color). The functions then returns
always a single color string """
if type(color) == tuple:
return color[appearance_mode]
else:
return color
@staticmethod
def rgb2hex(rgb_color: tuple) -> str:
return "#{:02x}{:02x}{:02x}".format(round(rgb_color[0]), round(rgb_color[1]), round(rgb_color[2]))
@staticmethod
def hex2rgb(hex_color: str) -> tuple:
return tuple(int(hex_color.strip("#")[i:i+2], 16) for i in (0, 2, 4))
@classmethod
def linear_blend(cls, color_1: str, color_2: str, blend_factor: float) -> str:
""" Blends two hex colors linear, where blend_factor of 0
results in color_1 and blend_factor of 1 results in color_2. """
if color_1 is None or color_2 is None:
return None
rgb_1 = cls.hex2rgb(color_1)
rgb_2 = cls.hex2rgb(color_2)
new_rgb = (rgb_1[0] + (rgb_2[0] - rgb_1[0]) * blend_factor,
rgb_1[1] + (rgb_2[1] - rgb_1[1]) * blend_factor,
rgb_1[2] + (rgb_2[2] - rgb_1[2]) * blend_factor)
return cls.rgb2hex(new_rgb)
@classmethod
def darken_hex_color(cls, hex_color: str, darken_factor: float = None) -> str:
if darken_factor is None:
darken_factor = cls.DARKEN_COLOR_FACTOR
try:
rgb_color = CTkColorManager.hex2rgb(hex_color)
dark_rgb_color = (rgb_color[0] * darken_factor,
rgb_color[1] * darken_factor,
rgb_color[2] * darken_factor)
return CTkColorManager.rgb2hex(dark_rgb_color)
except Exception as err:
sys.stderr.write("ERROR (CTkColorManager): failed to darken the following color: " + str(hex_color) + " " + str(err))
return hex_color
@classmethod
def set_main_color(cls, main_color, main_color_hover):
cls.MAIN = main_color
cls.MAIN_HOVER = main_color_hover
CTkColorManager.initialize_color_theme("blue")

View File

@ -4,7 +4,7 @@ import time
from customtkinter.customtkinter_label import CTkLabel
from customtkinter.customtkinter_button import CTkButton
from customtkinter.customtkinter_entry import CTkEntry
from customtkinter.customtkinter_color_manager import CTkColorManager
from customtkinter.customtkinter_theme_manager import CTkThemeManager
class CTkDialog:
@ -12,8 +12,8 @@ class CTkDialog:
master=None,
title="CTkDialog",
text="CTkDialog",
fg_color="CTkColorManager",
hover_color="CTkColorManager"):
fg_color="default_theme",
hover_color="default_theme"):
self.master = master
self.user_input = None
@ -21,8 +21,8 @@ class CTkDialog:
self.height = len(text.split("\n"))*20 + 150
self.fg_color = CTkColorManager.MAIN if fg_color == "CTkColorManager" else fg_color
self.hover_color = CTkColorManager.MAIN_HOVER if hover_color == "CTkColorManager" else hover_color
self.fg_color = CTkThemeManager.MAIN_COLOR if fg_color == "default_theme" else fg_color
self.hover_color = CTkThemeManager.MAIN_HOVER_COLOR if hover_color == "default_theme" else hover_color
self.top = customtkinter.CTkToplevel()
self.top.geometry(f"280x{self.height}")

View File

@ -4,16 +4,16 @@ import sys
from .customtkinter_tk import CTk
from .customtkinter_frame import CTkFrame
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
class CTkEntry(tkinter.Frame):
def __init__(self, *args,
master=None,
bg_color=None,
fg_color="CTkColorManager",
text_color="CTkColorManager",
placeholder_text_color="CTkColorManager",
fg_color="default_theme",
text_color="default_theme",
placeholder_text_color="default_theme",
text_font=None,
placeholder_text=None,
corner_radius=8,
@ -52,9 +52,9 @@ class CTkEntry(tkinter.Frame):
self.configure_basic_grid()
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
self.fg_color = CTkColorManager.ENTRY if fg_color == "CTkColorManager" else fg_color
self.text_color = CTkColorManager.TEXT if text_color == "CTkColorManager" else text_color
self.placeholder_text_color = CTkColorManager.PLACEHOLDER_TEXT if placeholder_text_color == "CTkColorManager" else placeholder_text_color
self.fg_color = CTkThemeManager.ENTRY_COLOR if fg_color == "default_theme" else fg_color
self.text_color = CTkThemeManager.TEXT_COLOR if text_color == "default_theme" else text_color
self.placeholder_text_color = CTkThemeManager.PLACEHOLDER_TEXT_COLOR if placeholder_text_color == "default_theme" else placeholder_text_color
if text_font is None:
if sys.platform == "darwin": # macOS
@ -152,14 +152,14 @@ class CTkEntry(tkinter.Frame):
if not self.placeholder_text_active and self.entry.get() == "":
self.placeholder_text_active = True
self.pre_placeholder_arguments = {"show": self.entry.cget("show")}
self.entry.config(fg=CTkColorManager.single_color(self.placeholder_text_color, self.appearance_mode), show="")
self.entry.config(fg=CTkThemeManager.single_color(self.placeholder_text_color, self.appearance_mode), show="")
self.entry.delete(0, tkinter.END)
self.entry.insert(0, self.placeholder_text)
def clear_placeholder(self, event=None):
if self.placeholder_text_active:
self.placeholder_text_active = False
self.entry.config(fg=CTkColorManager.single_color(self.text_color, self.appearance_mode))
self.entry.config(fg=CTkThemeManager.single_color(self.text_color, self.appearance_mode))
self.entry.delete(0, tkinter.END)
for argument, value in self.pre_placeholder_arguments.items():
self.entry[argument] = value

View File

@ -3,13 +3,13 @@ import sys
from .customtkinter_tk import CTk
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
class CTkFrame(tkinter.Frame):
def __init__(self, *args,
bg_color=None,
fg_color="CTkColorManager",
fg_color="default_theme",
corner_radius=10,
width=200,
height=200,
@ -42,14 +42,14 @@ class CTkFrame(tkinter.Frame):
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
if fg_color == "CTkColorManager":
if fg_color == "default_theme":
if isinstance(self.master, CTkFrame):
if self.master.fg_color == CTkColorManager.FRAME:
self.fg_color = CTkColorManager.FRAME_2
if self.master.fg_color == CTkThemeManager.FRAME_COLOR:
self.fg_color = CTkThemeManager.FRAME_2_COLOR
else:
self.fg_color = CTkColorManager.FRAME
self.fg_color = CTkThemeManager.FRAME_COLOR
else:
self.fg_color = CTkColorManager.FRAME
self.fg_color = CTkThemeManager.FRAME_COLOR
else:
self.fg_color = fg_color

View File

@ -4,15 +4,15 @@ import sys
from .customtkinter_tk import CTk
from .customtkinter_frame import CTkFrame
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
class CTkLabel(tkinter.Frame):
def __init__(self, *args,
master=None,
bg_color=None,
fg_color="CTkColorManager",
text_color="CTkColorManager",
fg_color="default_theme",
text_color="default_theme",
corner_radius=8,
width=120,
height=25,
@ -49,8 +49,8 @@ class CTkLabel(tkinter.Frame):
self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
self.fg_color = CTkColorManager.LABEL_BG if fg_color == "CTkColorManager" else fg_color
self.text_color = CTkColorManager.TEXT if text_color == "CTkColorManager" else text_color
self.fg_color = CTkThemeManager.LABEL_BG_COLOR if fg_color == "default_theme" else fg_color
self.text_color = CTkThemeManager.TEXT_COLOR if text_color == "default_theme" else text_color
self.width = width
self.height = height

View File

@ -4,7 +4,7 @@ import tkinter
from .customtkinter_tk import CTk
from .customtkinter_frame import CTkFrame
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
class CTkProgressBar(tkinter.Frame):
@ -13,9 +13,9 @@ class CTkProgressBar(tkinter.Frame):
def __init__(self, *args,
variable=None,
bg_color=None,
border_color="CTkColorManager",
fg_color="CTkColorManager",
progress_color="CTkColorManager",
border_color="default_theme",
fg_color="default_theme",
progress_color="default_theme",
width=160,
height=10,
border_width=0,
@ -47,9 +47,9 @@ class CTkProgressBar(tkinter.Frame):
self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
self.border_color = CTkColorManager.PROGRESS_BG if border_color == "CTkColorManager" else border_color
self.fg_color = CTkColorManager.PROGRESS_BG if fg_color == "CTkColorManager" else fg_color
self.progress_color = CTkColorManager.MAIN if progress_color == "CTkColorManager" else progress_color
self.border_color = CTkThemeManager.PROGRESS_BG_COLOR if border_color == "default_theme" else border_color
self.fg_color = CTkThemeManager.PROGRESS_BG_COLOR if fg_color == "default_theme" else fg_color
self.progress_color = CTkThemeManager.MAIN_COLOR if progress_color == "default_theme" else progress_color
self.variable = variable
self.variable_callback_blocked = False
@ -125,10 +125,10 @@ class CTkProgressBar(tkinter.Frame):
self.draw_with_ovals_and_rects()
if no_color_updates is False:
self.canvas.configure(bg=CTkColorManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts", fill=CTkColorManager.single_color(self.border_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts", fill=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("progress_parts", fill=CTkColorManager.single_color(self.progress_color, self.appearance_mode))
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.progress_color, self.appearance_mode))
def draw_with_polygon_shapes(self):
""" draw the progress bar parts with just three polygons that have a rounded border """

View File

@ -0,0 +1,6 @@
import sys
class CTkSettings:
scaling_factor = 1

View File

@ -4,7 +4,7 @@ import sys
from .customtkinter_tk import CTk
from .customtkinter_frame import CTkFrame
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
class CTkSlider(tkinter.Frame):
@ -13,10 +13,10 @@ class CTkSlider(tkinter.Frame):
def __init__(self, *args,
bg_color=None,
border_color=None,
fg_color="CTkColorManager",
progress_color="CTkColorManager",
button_color="CTkColorManager",
button_hover_color="CTkColorManager",
fg_color="default_theme",
progress_color="default_theme",
button_color="default_theme",
button_hover_color="default_theme",
from_=0,
to=1,
number_of_steps=None,
@ -54,10 +54,10 @@ class CTkSlider(tkinter.Frame):
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
self.border_color = border_color
self.fg_color = CTkColorManager.SLIDER_BG if fg_color == "CTkColorManager" else fg_color
self.progress_color = CTkColorManager.SLIDER_PROGRESS if progress_color == "CTkColorManager" else progress_color
self.button_color = CTkColorManager.MAIN if button_color == "CTkColorManager" else button_color
self.button_hover_color = CTkColorManager.MAIN_HOVER if button_hover_color == "CTkColorManager" else button_hover_color
self.fg_color = CTkThemeManager.SLIDER_BG_COLOR if fg_color == "default_theme" else fg_color
self.progress_color = CTkThemeManager.SLIDER_PROGRESS_COLOR if progress_color == "default_theme" else progress_color
self.button_color = CTkThemeManager.MAIN_COLOR if button_color == "default_theme" else button_color
self.button_hover_color = CTkThemeManager.MAIN_HOVER_COLOR if button_hover_color == "default_theme" else button_hover_color
self.width = width
self.height = self.calc_optimal_height(height)
@ -148,21 +148,21 @@ class CTkSlider(tkinter.Frame):
self.draw_with_ovals_and_rects()
if no_color_updates is False:
self.canvas.configure(bg=CTkColorManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
if self.border_color is None:
self.canvas.itemconfig("border_parts", fill=CTkColorManager.single_color(self.bg_color, self.appearance_mode))
self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
else:
self.canvas.itemconfig("border_parts", fill=CTkColorManager.single_color(self.border_color, self.appearance_mode))
self.canvas.itemconfig("border_parts", fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts", fill=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("inner_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
if self.progress_color is None:
self.canvas.itemconfig("progress_parts", fill=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
else:
self.canvas.itemconfig("progress_parts", fill=CTkColorManager.single_color(self.progress_color, self.appearance_mode))
self.canvas.itemconfig("progress_parts", fill=CTkThemeManager.single_color(self.progress_color, self.appearance_mode))
self.canvas.itemconfig("button_parts", fill=CTkColorManager.single_color(self.button_color, self.appearance_mode))
self.canvas.itemconfig("button_parts", fill=CTkThemeManager.single_color(self.button_color, self.appearance_mode))
def draw_with_polygon_shapes(self):
""" draw the slider parts with just three polygons that have a rounded border """
@ -327,11 +327,11 @@ class CTkSlider(tkinter.Frame):
def on_enter(self, event=0):
self.hover_state = True
self.canvas.itemconfig("button_parts", fill=CTkColorManager.single_color(self.button_hover_color, self.appearance_mode))
self.canvas.itemconfig("button_parts", fill=CTkThemeManager.single_color(self.button_hover_color, self.appearance_mode))
def on_leave(self, event=0):
self.hover_state = False
self.canvas.itemconfig("button_parts", fill=CTkColorManager.single_color(self.button_color, self.appearance_mode))
self.canvas.itemconfig("button_parts", fill=CTkThemeManager.single_color(self.button_color, self.appearance_mode))
def round_to_step_size(self, value):
if self.number_of_steps is not None:

View File

@ -0,0 +1,129 @@
import sys
class CTkThemeManager:
WINDOW_BG_COLOR = None
MAIN_COLOR = None
MAIN_HOVER_COLOR = None
ENTRY_COLOR = None
TEXT_COLOR = None
PLACEHOLDER_TEXT_COLOR = None
LABEL_BG_COLOR = None
SLIDER_BG_COLOR = None
SLIDER_PROGRESS_COLOR = None
PROGRESS_BG_COLOR = None
FRAME_COLOR = None
FRAME_2_COLOR = None
CHECKBOX_LINES_COLOR = None
DARKEN_COLOR_FACTOR = None
@classmethod
def initialize_color_theme(cls, theme_name):
if theme_name.lower() == "blue":
cls.WINDOW_BG_COLOR = ("#ECECEC", "#323232") # macOS standard light and dark window bg colors
cls.MAIN_COLOR = ("#64A1D2", "#1C94CF")
cls.MAIN_HOVER_COLOR = ("#A7C2E0", "#5FB4DD")
cls.ENTRY_COLOR = ("white", "#222222")
cls.TEXT_COLOR = ("black", "white")
cls.PLACEHOLDER_TEXT_COLOR = ("gray52", "gray62")
cls.LABEL_BG_COLOR = ("white", "#626061")
cls.SLIDER_BG_COLOR = ("#6B6B6B", "#222222")
cls.SLIDER_PROGRESS_COLOR = ("#A5A6A5", "#555555")
cls.PROGRESS_BG_COLOR = ("#6B6B6B", "#222222")
cls.FRAME_COLOR = ("#D4D5D6", "#3F3F3F")
cls.FRAME_2_COLOR = ("#BFBEC1", "#505050")
cls.CHECKBOX_LINES_COLOR = ("black", "#ededed")
cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button
elif theme_name.lower() == "green":
cls.WINDOW_BG_COLOR = ("#ECECEC", "#323232") # macOS standard light and dark window bg colors
cls.MAIN_COLOR = ("#13C995", "#1ABE87")
cls.MAIN_HOVER_COLOR = ("#6ACBA5", "#81E4B2")
cls.ENTRY_COLOR = ("gray60", "#222223")
cls.TEXT_COLOR = ("gray25", "gray92")
cls.PLACEHOLDER_TEXT_COLOR = ("gray32", "gray55")
cls.LABEL_BG_COLOR = ("white", "#626061")
cls.SLIDER_BG_COLOR = ("#636363", "#0D1321")
cls.SLIDER_PROGRESS_COLOR = ("white", "#727578")
cls.PROGRESS_BG_COLOR = ("#636363", "#0D1321")
cls.FRAME_COLOR = ("#D4D5D6", "#3F3F3F")
cls.FRAME_2_COLOR = ("#BFBEC1", "#505050")
cls.CHECKBOX_LINES_COLOR = ("#414141", "#EDEDED")
cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button
elif theme_name.lower() == "dark-blue":
cls.WINDOW_BG_COLOR = ("#F1F1F1", "#192026") # macOS standard light and dark window bg colors
cls.MAIN_COLOR = ("#608BD5", "#395E9C")
cls.MAIN_HOVER_COLOR = ("#A4BDE6", "#748BB3")
cls.ENTRY_COLOR = ("#FCFCFC", "#111116")
cls.TEXT_COLOR = ("black", "white")
cls.PLACEHOLDER_TEXT_COLOR = ("gray52", "gray62")
cls.LABEL_BG_COLOR = ("white", "#444444")
cls.SLIDER_BG_COLOR = ("#444444", "#444444")
cls.SLIDER_PROGRESS_COLOR = ("white", "#AAAAAA")
cls.PROGRESS_BG_COLOR = ("#636363", "#0D1321")
cls.FRAME_COLOR = ("#DADADA", "#2B2C2E")
cls.FRAME_2_COLOR = ("#C4C4C4", "#383838")
cls.CHECKBOX_LINES_COLOR = ("#313131", "white")
cls.DARKEN_COLOR_FACTOR = 0.8 # used to generate color for disabled button
@staticmethod
def single_color(color, appearance_mode: int) -> str:
""" color can be either a single hex color string or a color name or it can be a
tuple color with (light_color, dark_color). The functions then returns
always a single color string """
if type(color) == tuple:
return color[appearance_mode]
else:
return color
@staticmethod
def rgb2hex(rgb_color: tuple) -> str:
return "#{:02x}{:02x}{:02x}".format(round(rgb_color[0]), round(rgb_color[1]), round(rgb_color[2]))
@staticmethod
def hex2rgb(hex_color: str) -> tuple:
return tuple(int(hex_color.strip("#")[i:i+2], 16) for i in (0, 2, 4))
@classmethod
def linear_blend(cls, color_1: str, color_2: str, blend_factor: float) -> str:
""" Blends two hex colors linear, where blend_factor of 0
results in color_1 and blend_factor of 1 results in color_2. """
if color_1 is None or color_2 is None:
return None
rgb_1 = cls.hex2rgb(color_1)
rgb_2 = cls.hex2rgb(color_2)
new_rgb = (rgb_1[0] + (rgb_2[0] - rgb_1[0]) * blend_factor,
rgb_1[1] + (rgb_2[1] - rgb_1[1]) * blend_factor,
rgb_1[2] + (rgb_2[2] - rgb_1[2]) * blend_factor)
return cls.rgb2hex(new_rgb)
@classmethod
def darken_hex_color(cls, hex_color: str, darken_factor: float = None) -> str:
if darken_factor is None:
darken_factor = cls.DARKEN_COLOR_FACTOR
try:
rgb_color = CTkThemeManager.hex2rgb(hex_color)
dark_rgb_color = (rgb_color[0] * darken_factor,
rgb_color[1] * darken_factor,
rgb_color[2] * darken_factor)
return CTkThemeManager.rgb2hex(dark_rgb_color)
except Exception as err:
sys.stderr.write("ERROR (CTkColorManager): failed to darken the following color: " + str(hex_color) + " " + str(err))
return hex_color
@classmethod
def set_main_color(cls, main_color, main_color_hover):
cls.MAIN_COLOR = main_color
cls.MAIN_HOVER_COLOR = main_color_hover
CTkThemeManager.initialize_color_theme("blue")

View File

@ -6,19 +6,19 @@ import platform
import ctypes
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
class CTk(tkinter.Tk):
def __init__(self, *args,
fg_color="CTkColorManager",
fg_color="default_theme",
**kwargs):
self.enable_macos_dark_title_bar()
super().__init__(*args, **kwargs)
self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
self.fg_color = CTkColorManager.WINDOW_BG if fg_color == "CTkColorManager" else fg_color
self.fg_color = CTkThemeManager.WINDOW_BG_COLOR if fg_color == "default_theme" else fg_color
if "bg" in kwargs:
self.fg_color = kwargs["bg"]
@ -28,7 +28,8 @@ class CTk(tkinter.Tk):
del kwargs["background"]
AppearanceModeTracker.add(self.set_appearance_mode, self)
super().configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
super().title("CTk")
self.window_exists = False # indicates if the window is already shown through .update or .mainloop
@ -73,14 +74,14 @@ class CTk(tkinter.Tk):
if "bg" in kwargs:
self.fg_color = kwargs["bg"]
bg_changed = True
kwargs["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "background" in kwargs:
self.fg_color = kwargs["background"]
bg_changed = True
kwargs["background"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
kwargs["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "fg_color" in kwargs:
self.fg_color = kwargs["fg_color"]
kwargs["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
del kwargs["fg_color"]
bg_changed = True
@ -88,11 +89,11 @@ class CTk(tkinter.Tk):
if "bg" in args[0]:
self.fg_color=args[0]["bg"]
bg_changed = True
args[0]["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
args[0]["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "background" in args[0]:
self.fg_color=args[0]["background"]
bg_changed = True
args[0]["background"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
args[0]["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
if bg_changed:
from .customtkinter_slider import CTkSlider
@ -181,4 +182,4 @@ class CTk(tkinter.Tk):
else:
self.windows_set_titlebar_color("light")
super().configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))

View File

@ -6,19 +6,19 @@ import platform
import ctypes
from .appearance_mode_tracker import AppearanceModeTracker
from .customtkinter_color_manager import CTkColorManager
from .customtkinter_theme_manager import CTkThemeManager
class CTkToplevel(tkinter.Toplevel):
def __init__(self, *args,
fg_color="CTkColorManager",
fg_color="default_theme",
**kwargs):
self.enable_macos_dark_title_bar()
super().__init__(*args, **kwargs)
self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
self.fg_color = CTkColorManager.WINDOW_BG if fg_color == "CTkColorManager" else fg_color
self.fg_color = CTkThemeManager.WINDOW_BG_COLOR if fg_color == "default_theme" else fg_color
if "bg" in kwargs:
self.fg_color = kwargs["bg"]
@ -28,7 +28,8 @@ class CTkToplevel(tkinter.Toplevel):
del kwargs["background"]
AppearanceModeTracker.add(self.set_appearance_mode, self)
super().configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))
super().title("CTkToplevel")
if sys.platform.startswith("win"):
if self.appearance_mode == 1:
@ -59,14 +60,14 @@ class CTkToplevel(tkinter.Toplevel):
if "bg" in kwargs:
self.fg_color = kwargs["bg"]
bg_changed = True
kwargs["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "background" in kwargs:
self.fg_color = kwargs["background"]
bg_changed = True
kwargs["background"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
kwargs["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "fg_color" in kwargs:
self.fg_color = kwargs["fg_color"]
kwargs["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
kwargs["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
del kwargs["fg_color"]
bg_changed = True
@ -74,11 +75,11 @@ class CTkToplevel(tkinter.Toplevel):
if "bg" in args[0]:
self.fg_color=args[0]["bg"]
bg_changed = True
args[0]["bg"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
args[0]["bg"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
elif "background" in args[0]:
self.fg_color=args[0]["background"]
bg_changed = True
args[0]["background"] = CTkColorManager.single_color(self.fg_color, self.appearance_mode)
args[0]["background"] = CTkThemeManager.single_color(self.fg_color, self.appearance_mode)
if bg_changed:
from .customtkinter_slider import CTkSlider
@ -164,4 +165,4 @@ class CTkToplevel(tkinter.Toplevel):
else:
self.windows_set_titlebar_color("light")
super().configure(bg=CTkColorManager.single_color(self.fg_color, self.appearance_mode))
super().configure(bg=CTkThemeManager.single_color(self.fg_color, self.appearance_mode))

View File

@ -53,7 +53,7 @@ class App(customtkinter.CTk):
text="CTkButton",
command=self.button_event,
border_width=3,
corner_radius=5)
corner_radius=6)
self.button_1.place(relx=0.5, y=50, anchor=tkinter.CENTER)
self.button_2 = customtkinter.CTkButton(master=self.frame_left,
@ -63,7 +63,7 @@ class App(customtkinter.CTk):
text="CTkButton",
command=self.button_event,
border_width=3,
corner_radius=5)
corner_radius=6)
self.button_2.place(relx=0.5, y=100, anchor=tkinter.CENTER)
self.button_3 = customtkinter.CTkButton(master=self.frame_left,
@ -73,7 +73,7 @@ class App(customtkinter.CTk):
text="CTkButton",
command=self.button_event,
border_width=3,
corner_radius=5)
corner_radius=6)
self.button_3.place(relx=0.5, y=150, anchor=tkinter.CENTER)
# ============ frame_right ============
@ -93,7 +93,7 @@ class App(customtkinter.CTk):
"invidunt ut labore",
width=250,
height=100,
corner_radius=5,
corner_radius=6,
fg_color=("white", "gray20"),
text_color=App.MAIN_COLOR,
justify=tkinter.LEFT)
@ -145,13 +145,13 @@ class App(customtkinter.CTk):
text="CTkButton",
command=self.button_event,
border_width=3,
corner_radius=5)
corner_radius=6)
self.button_4.place(x=310, rely=0.7, anchor=tkinter.CENTER)
self.entry = customtkinter.CTkEntry(master=self.frame_right,
width=120,
height=28,
corner_radius=5)
corner_radius=6)
self.entry.place(relx=0.33, rely=0.92, anchor=tkinter.CENTER)
self.entry.insert(0, "CTkEntry")
@ -163,7 +163,7 @@ class App(customtkinter.CTk):
text="CTkButton",
command=self.button_event,
border_width=3,
corner_radius=5)
corner_radius=6)
self.button_5.place(relx=0.66, rely=0.92, anchor=tkinter.CENTER)
def button_event(self):

View File

@ -32,7 +32,7 @@ label_1.pack(pady=y_padding, padx=10)
progressbar_1 = customtkinter.CTkProgressBar(master=frame_1)
progressbar_1.pack(pady=y_padding, padx=10)
button_1 = customtkinter.CTkButton(master=frame_1, corner_radius=10, command=button_function)
button_1 = customtkinter.CTkButton(master=frame_1, corner_radius=8, command=button_function)
button_1.pack(pady=y_padding, padx=10)
# button_1.configure(state="disabled")

View File

@ -65,7 +65,7 @@ class TestApp(customtkinter.CTk):
self.frame_2 = customtkinter.CTkFrame(master=self.ctk_frame, width=200, height=60)
self.frame_2.place(relx=0.5, y=y + 80, anchor=tkinter.CENTER)
self.button_2 = customtkinter.CTkButton(master=self.ctk_frame, border_width=3, border_color=customtkinter.CTkColorManager.MAIN_HOVER,
self.button_2 = customtkinter.CTkButton(master=self.ctk_frame, border_width=3, border_color=customtkinter.CTkThemeManager.MAIN_HOVER_COLOR,
)
self.button_2.place(relx=0.5, y=y + 160, anchor=tkinter.CENTER)

View File

@ -1,7 +1,13 @@
#import tkinter.ttk as ttk
import ctypes
print(ctypes.windll.shcore.SetProcessDpiAwareness(ctypes.c_int(1)))
import tkinter
import tkinter.ttk as ttk
app = tkinter.Tk()
print(app.winfo_fpixels('1i'))
#app.tk.call('tk', 'scaling', 1.0)
print(app.winfo_fpixels('1i'))
app.geometry("400x300")
app.title("Standard Tkinter Test")
@ -22,9 +28,9 @@ frame_1.pack(padx=60, pady=20, fill="both", expand=True)
label_1 = tkinter.Label(master=frame_1, text="Label", bg="lightgray")
label_1.pack(pady=y_padding, padx=10)
progressbar_1 = ttk.Progressbar(master=frame_1,style='black.Horizontal.TProgressbar', length=150)
progressbar_1.pack(pady=y_padding, padx=10)
progressbar_1["value"] = 50
#progressbar_1 = ttk.Progressbar(master=frame_1,style='black.Horizontal.TProgressbar', length=150)
#progressbar_1.pack(pady=y_padding, padx=10)
#progressbar_1["value"] = 50
button_1 = tkinter.Button(master=frame_1, command=button_function, text="Button", highlightbackground="lightgray")
button_1.pack(pady=y_padding, padx=10)