finished CTkFont support for button, label, checkbox, created test_font.py

This commit is contained in:
Tom Schimansky 2022-10-21 21:28:31 +02:00
parent 1ae794272b
commit 42fb7f2186
11 changed files with 225 additions and 82 deletions

View File

@ -5,10 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
ToDo: ToDo:
- - enforce font size in pixel and enforce CTkFont class
- remove bg and background support for CTk and CTkToplevel (to be done)
- enforce font size in pixel
- enforce font to be tuple
- complete other theme files - complete other theme files
- auto scaling of images - auto scaling of images
@ -28,6 +25,7 @@ ToDo:
### Removed ### Removed
- Removed setter and getter functions like set_text in CTkButton - Removed setter and getter functions like set_text in CTkButton
- Removed bg and background attribute from CTk and CTkToplevel, always use fg_color
### Fixed ### Fixed

View File

@ -74,7 +74,7 @@ from .windows.ctk_toplevel import CTkToplevel
from .windows.ctk_input_dialog import CTkInputDialog from .windows.ctk_input_dialog import CTkInputDialog
# util classes # util classes
from .utility.ctk_font import CTkFont from .utility.ctk_font import CTkFont as _CTkFont
def set_appearance_mode(mode_string: str): def set_appearance_mode(mode_string: str):

View File

@ -1,15 +1,25 @@
from tkinter.font import Font from tkinter.font import Font
import copy import copy
import sys from typing import List, Callable, Tuple
from ..scaling_tracker import ScalingTracker
from ..theme_manager import ThemeManager from ..theme_manager import ThemeManager
class CTkFont(Font): class CTkFont(Font):
""" """
Font object with size in pixel independent of scaling. Font object with size in pixel, independent of scaling.
To get scaled tuple representation use create_scaled_tuple() method.
family The font family name as a string.
size The font height as an integer in pixel.
weight 'bold' for boldface, 'normal' for regular weight.
slant 'italic' for italic, 'roman' for unslanted.
underline 1 for underlined text, 0 for normal.
overstrike 1 for overstruck text, 0 for normal.
Tkinter Font: https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/fonts.html
""" """
def __init__(self, def __init__(self,
family: str = "default_theme", family: str = "default_theme",
size: int = "default_theme", size: int = "default_theme",
@ -18,34 +28,30 @@ class CTkFont(Font):
underline: bool = False, underline: bool = False,
overstrike: bool = False): overstrike: bool = False):
# unscaled font size in px self._size_configure_callback_list: List[Callable] = []
self._size = ThemeManager.theme["text"]["size"] if size == "default_theme" else size
if self._size < 0: self._family = family
sys.stderr.write(f"Warning: size {self._size} of CTkFont don't has to be negative, it's measured in pixel by default\n") self._size = ThemeManager.theme["text"]["size"] if size == "default_theme" else size
self._tuple_style_string = f"{weight} {slant} {'underline' if underline else ''} {'overstrike' if overstrike else ''}"
super().__init__(family=ThemeManager.theme["text"]["font"] if family == "default_theme" else family, super().__init__(family=ThemeManager.theme["text"]["font"] if family == "default_theme" else family,
size=self._size, size=-abs(self._size),
weight=weight, weight=weight,
slant=slant, slant=slant,
underline=underline, underline=underline,
overstrike=overstrike) overstrike=overstrike)
def _set_scaling(self, new_widget_scaling, new_spacing_scaling, new_window_scaling): def add_size_configure_callback(self, callback: Callable):
self._widget_scaling = new_widget_scaling """ add function, that gets called when font got configured """
super().configure(size=round(self._apply_widget_scaling(self._size))) self._size_configure_callback_list.append(callback)
def _apply_widget_scaling(self, value: int) -> int: def remove_size_configure_callback(self, callback: Callable):
if isinstance(value, int): """ remove function, that gets called when font got configured """
return round(value * self._widget_scaling) self._size_configure_callback_list.remove(callback)
else:
raise ValueError(f"CTkFont can not scale size of type {type(value)}, only int allowed")
def _reverse_widget_scaling(self, value: int) -> int: def create_scaled_tuple(self, font_scaling: float) -> Tuple[str, int, str]:
if isinstance(value, int): """ return scaled tuple representation of font in the form (family: str, size: int, style: str)"""
return round(value / self._widget_scaling) return self._family, round(self._size * font_scaling), self._tuple_style_string
else:
raise ValueError(f"CTkFont can not scale size of type {type(value)}, only int allowed")
def config(self, *args, **kwargs): def config(self, *args, **kwargs):
raise AttributeError("'config' is not implemented for CTk widgets. For consistency, always use 'configure' instead.") raise AttributeError("'config' is not implemented for CTk widgets. For consistency, always use 'configure' instead.")
@ -53,42 +59,22 @@ class CTkFont(Font):
def configure(self, **kwargs): def configure(self, **kwargs):
if "size" in kwargs: if "size" in kwargs:
self._size = kwargs.pop("size") self._size = kwargs.pop("size")
super().configure(size=self._apply_widget_scaling(self._size)) super().configure(size=-abs(self._size))
super().configure(**kwargs) super().configure(**kwargs)
def cget(self, attribute_name) -> any: # update style string for create_scaled_tuple() method
self._tuple_style_string = f"{super().cget('weight')} {super().cget('slant')} {'underline' if super().cget('underline') else ''} {'overstrike' if super().cget('overstrike') else ''}"
# call all functions registered with add_size_configure_callback()
for callback in self._size_configure_callback_list:
callback()
def cget(self, attribute_name: str) -> any:
if attribute_name == "size": if attribute_name == "size":
return self._size return self._size
else: else:
super().cget(attribute_name) return super().cget(attribute_name)
def copy(self) -> "CTkFont": def copy(self) -> "CTkFont":
return copy.deepcopy(self) return copy.deepcopy(self)
def measure(self, text, displayof=None) -> int:
""" measure width of text in px independent of scaling """
return self._reverse_widget_scaling(super().measure(text, displayof=displayof))
def metrics(self, *options: any, **kw: any) -> dict:
""" metrics of font, all values independent of scaling """
metrics_dict = super().metrics(*options, **kw)
if "ascent" in metrics_dict:
metrics_dict["ascent"] = self._reverse_widget_scaling(metrics_dict["ascent"])
if "descent" in metrics_dict:
metrics_dict["descent"] = self._reverse_widget_scaling(metrics_dict["descent"])
if "linespace" in metrics_dict:
metrics_dict["linespace"] = self._reverse_widget_scaling(metrics_dict["linespace"])
return metrics_dict
def actual(self, option: any = None, displayof: any = None) -> dict:
""" get back a dictionary of the font's actual attributes, which may differ from the ones you requested, size independent of scaling """
actual_dict = super().actual(option, displayof)
if "size" in actual_dict:
actual_dict["size"] = self._reverse_widget_scaling(actual_dict["size"])
return actual_dict

View File

@ -63,12 +63,16 @@ class CTkButton(CTkBaseClass):
self._corner_radius = min(self._corner_radius, round(self._current_height/2)) self._corner_radius = min(self._corner_radius, round(self._current_height/2))
# text, font, image # text, image
self._image = image self._image = image
self._image_label: Union[tkinter.Label, None] = None self._image_label: Union[tkinter.Label, None] = None
self._text = text self._text = text
self._text_label: Union[tkinter.Label, None] = None self._text_label: Union[tkinter.Label, None] = None
self._font = CTkFont() if font == "default_theme" else self._check_font_type_and_values(font)
# font
self._font = CTkFont() if font == "default_theme" else self._check_font_type(font)
if isinstance(self._font, CTkFont):
self._font.add_size_configure_callback(self._update_font)
# callback and hover functionality # callback and hover functionality
self._command = command self._command = command
@ -120,6 +124,21 @@ class CTkButton(CTkBaseClass):
height=self._apply_widget_scaling(self._desired_height)) height=self._apply_widget_scaling(self._desired_height))
self._draw() self._draw()
def _update_font(self):
""" pass font to tkinter widgets with applied font scaling and update grid with workaround """
if self._text_label is not None:
self._text_label.configure(font=self._apply_font_scaling(self._font))
# Workaround to force grid to be resized when text changes size.
# Otherwise grid will lag and only resizes if other mouse action occurs.
self._canvas.grid_forget()
self._canvas.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="nsew")
def destroy(self):
if isinstance(self._font, CTkFont):
self._font.remove_size_configure_callback(self._update_font)
super().destroy()
def _draw(self, no_color_updates=False): def _draw(self, no_color_updates=False):
if self._background_corner_colors is not None: if self._background_corner_colors is not None:
self._draw_engine.draw_background_corners(self._apply_widget_scaling(self._current_width), self._draw_engine.draw_background_corners(self._apply_widget_scaling(self._current_width),
@ -269,7 +288,12 @@ class CTkButton(CTkBaseClass):
self._text_label.configure(text=self._text) self._text_label.configure(text=self._text)
if "font" in kwargs: if "font" in kwargs:
self._font = kwargs.pop("font") if isinstance(self._font, CTkFont):
self._font.remove_size_configure_callback(self._update_font)
self._font = self._check_font_type(kwargs.pop("font"))
if isinstance(self._font, CTkFont):
self._font.add_size_configure_callback(self._update_font)
if self._text_label is not None: if self._text_label is not None:
self._text_label.configure(font=self._apply_font_scaling(self._font)) self._text_label.configure(font=self._apply_font_scaling(self._font))

View File

@ -7,6 +7,7 @@ from ..theme_manager import ThemeManager
from ..settings import Settings from ..settings import Settings
from ..draw_engine import DrawEngine from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass from .widget_base_class import CTkBaseClass
from ..utility.ctk_font import CTkFont
class CTkCheckBox(CTkBaseClass): class CTkCheckBox(CTkBaseClass):
@ -33,7 +34,7 @@ class CTkCheckBox(CTkBaseClass):
text_color_disabled: Union[str, Tuple[str, str]] = "default_theme", text_color_disabled: Union[str, Tuple[str, str]] = "default_theme",
text: str = "CTkCheckBox", text: str = "CTkCheckBox",
font: any = "default_theme", font: Union[tuple, CTkFont] = "default_theme",
textvariable: tkinter.Variable = None, textvariable: tkinter.Variable = None,
state: str = tkinter.NORMAL, state: str = tkinter.NORMAL,
hover: bool = True, hover: bool = True,
@ -65,7 +66,11 @@ class CTkCheckBox(CTkBaseClass):
self._text_label: Union[tkinter.Label, None] = None self._text_label: Union[tkinter.Label, None] = None
self._text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color self._text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self._text_color_disabled = ThemeManager.theme["color"]["text_disabled"] if text_color_disabled == "default_theme" else text_color_disabled self._text_color_disabled = ThemeManager.theme["color"]["text_disabled"] if text_color_disabled == "default_theme" else text_color_disabled
self._font = (ThemeManager.theme["text"]["font"], ThemeManager.theme["text"]["size"]) if font == "default_theme" else font
# font
self._font = CTkFont() if font == "default_theme" else self._check_font_type(font)
if isinstance(self._font, CTkFont):
self._font.add_size_configure_callback(self._update_font)
# callback and hover functionality # callback and hover functionality
self._command = command self._command = command
@ -145,10 +150,23 @@ class CTkCheckBox(CTkBaseClass):
self._bg_canvas.configure(width=self._apply_widget_scaling(self._desired_width), self._bg_canvas.configure(width=self._apply_widget_scaling(self._desired_width),
height=self._apply_widget_scaling(self._desired_height)) height=self._apply_widget_scaling(self._desired_height))
def _update_font(self):
""" pass font to tkinter widgets with applied font scaling and update grid with workaround """
if self._text_label is not None:
self._text_label.configure(font=self._apply_font_scaling(self._font))
# Workaround to force grid to be resized when text changes size.
# Otherwise grid will lag and only resizes if other mouse action occurs.
self._bg_canvas.grid_forget()
self._bg_canvas.grid(row=0, column=0, sticky="nswe")
def destroy(self): def destroy(self):
if self._variable is not None: if self._variable is not None:
self._variable.trace_remove("write", self._variable_callback_name) self._variable.trace_remove("write", self._variable_callback_name)
if isinstance(self._font, CTkFont):
self._font.remove_size_configure_callback(self._update_font)
super().destroy() super().destroy()
def _draw(self, no_color_updates=False): def _draw(self, no_color_updates=False):
@ -212,9 +230,13 @@ class CTkCheckBox(CTkBaseClass):
self._text_label.configure(text=self._text) self._text_label.configure(text=self._text)
if "font" in kwargs: if "font" in kwargs:
self._font = kwargs.pop("font") if isinstance(self._font, CTkFont):
if self._text_label is not None: self._font.remove_size_configure_callback(self._update_font)
self._text_label.configure(font=self._apply_font_scaling(self._font)) self._font = self._check_font_type(kwargs.pop("font"))
if isinstance(self._font, CTkFont):
self._font.add_size_configure_callback(self._update_font)
self._update_font()
if "state" in kwargs: if "state" in kwargs:
self._state = kwargs.pop("state") self._state = kwargs.pop("state")

View File

@ -5,6 +5,7 @@ from .ctk_canvas import CTkCanvas
from ..theme_manager import ThemeManager from ..theme_manager import ThemeManager
from ..draw_engine import DrawEngine from ..draw_engine import DrawEngine
from .widget_base_class import CTkBaseClass from .widget_base_class import CTkBaseClass
from ..utility.ctk_font import CTkFont
from customtkinter.utility.utility_functions import pop_from_dict_by_set, check_kwargs_empty from customtkinter.utility.utility_functions import pop_from_dict_by_set, check_kwargs_empty
@ -30,7 +31,7 @@ class CTkLabel(CTkBaseClass):
text_color: Union[str, Tuple[str, str]] = "default_theme", text_color: Union[str, Tuple[str, str]] = "default_theme",
text: str = "CTkLabel", text: str = "CTkLabel",
font: any = "default_theme", font: Union[tuple, CTkFont] = "default_theme",
anchor: str = "center", # label anchor: center, n, e, s, w anchor: str = "center", # label anchor: center, n, e, s, w
**kwargs): **kwargs):
@ -47,7 +48,11 @@ class CTkLabel(CTkBaseClass):
# text # text
self._anchor = anchor self._anchor = anchor
self._text = text self._text = text
self._font = (ThemeManager.theme["text"]["font"], ThemeManager.theme["text"]["size"]) if font == "default_theme" else font
# font
self._font = CTkFont() if font == "default_theme" else self._check_font_type(font)
if isinstance(self._font, CTkFont):
self._font.add_size_configure_callback(self._update_font)
# configure grid system (1x1) # configure grid system (1x1)
self.grid_rowconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1)
@ -97,6 +102,20 @@ class CTkLabel(CTkBaseClass):
height=self._apply_widget_scaling(self._desired_height)) height=self._apply_widget_scaling(self._desired_height))
self._draw() self._draw()
def _update_font(self):
""" pass font to tkinter widgets with applied font scaling and update grid with workaround """
self._text_label.configure(font=self._apply_font_scaling(self._font))
# Workaround to force grid to be resized when text changes size.
# Otherwise grid will lag and only resizes if other mouse action occurs.
self._canvas.grid_forget()
self._canvas.grid(row=0, column=0, sticky="nswe")
def destroy(self):
if isinstance(self._font, CTkFont):
self._font.remove_size_configure_callback(self._update_font)
super().destroy()
def _draw(self, no_color_updates=False): def _draw(self, no_color_updates=False):
requires_recoloring = self._draw_engine.draw_rounded_rect_with_border(self._apply_widget_scaling(self._current_width), requires_recoloring = self._draw_engine.draw_rounded_rect_with_border(self._apply_widget_scaling(self._current_width),
self._apply_widget_scaling(self._current_height), self._apply_widget_scaling(self._current_height),
@ -133,8 +152,13 @@ class CTkLabel(CTkBaseClass):
self._text_label.configure(text=self._text) self._text_label.configure(text=self._text)
if "font" in kwargs: if "font" in kwargs:
self._font = kwargs.pop("font") if isinstance(self._font, CTkFont):
self._text_label.configure(font=self._apply_font_scaling(self._font)) self._font.remove_size_configure_callback(self._update_font)
self._font = self._check_font_type(kwargs.pop("font"))
if isinstance(self._font, CTkFont):
self._font.add_size_configure_callback(self._update_font)
self._update_font()
if "fg_color" in kwargs: if "fg_color" in kwargs:
self._fg_color = kwargs.pop("fg_color") self._fg_color = kwargs.pop("fg_color")

View File

@ -1,3 +1,4 @@
import sys
import tkinter import tkinter
import tkinter.ttk as ttk import tkinter.ttk as ttk
import copy import copy
@ -118,7 +119,7 @@ class CTkBaseClass(tkinter.Frame):
super().configure(**pop_from_dict_by_set(kwargs, self._valid_tk_frame_attributes)) # configure tkinter.Frame super().configure(**pop_from_dict_by_set(kwargs, self._valid_tk_frame_attributes)) # configure tkinter.Frame
# if there are still items in the kwargs dict, raise ValueError # if there are still items in the kwargs dict, raise ValueError
self._check_kwargs_empty(kwargs, raise_error=True) check_kwargs_empty(kwargs, raise_error=True)
if require_redraw: if require_redraw:
self._draw() self._draw()
@ -139,10 +140,23 @@ class CTkBaseClass(tkinter.Frame):
raise ValueError(f"'{attribute_name}' is not a supported argument. Look at the documentation for supported arguments.") raise ValueError(f"'{attribute_name}' is not a supported argument. Look at the documentation for supported arguments.")
@staticmethod @staticmethod
def _check_font_type_and_values(font: any): def _check_font_type(font: any):
if not isinstance(font, CTkFont): if isinstance(font, CTkFont):
raise ValueError(f"\nFor consistency, Customtkinter requires the font argument {font} to be an instance of CTkFont.\n" + return font
f"\nUsage example: font=customtkinter.CTkFont(family='name', size='size in px')\n(other arguments in the documentation)\n")
elif type(font) == tuple and len(font) == 1:
sys.stderr.write(f"Warning: font {font} given without size, will be extended with default text size of current theme\n")
return font[0], ThemeManager.theme["text"]["size"]
elif type(font) == tuple and 2 <= len(font) <= 3:
return font
else:
raise ValueError(f"Wrong font type {type(font)}\n" +
f"For consistency, Customtkinter requires the font argument to be a tuple of len 2 or 3 or an instance of CTkFont.\n" +
f"\nUsage example:\n" +
f"font=customtkinter.CTkFont(family='<name>', size=<size in px>)\n" +
f"font=('<name>', <size in px>)\n")
def _update_dimensions_event(self, event): def _update_dimensions_event(self, event):
# only redraw if dimensions changed (for performance), independent of scaling # only redraw if dimensions changed (for performance), independent of scaling
@ -219,15 +233,22 @@ class CTkBaseClass(tkinter.Frame):
else: else:
return value return value
def _apply_font_scaling(self, font: Union[tuple, CTkFont]) -> Union[tuple, CTkFont]: def _apply_font_scaling(self, font: Union[Tuple, CTkFont]) -> tuple:
""" Takes CTkFont object and returns tuple font with scaled size, has to be called again for every change of font object """
if type(font) == tuple: if type(font) == tuple:
font_list = list(font) if len(font) == 1:
if len(font_list) >= 2 and type(font_list[1]) == int: return font
font_list[1] = int(font_list[1] * self._widget_scaling) elif len(font) == 2:
return tuple(font_list) return font[0], round(font[1] * self._widget_scaling)
elif len(font) == 3:
return font[0], round(font[1] * self._widget_scaling), font[2]
else:
raise ValueError(f"Can not scale font {font}. font needs to be tuple of len 1, 2 or 3")
elif isinstance(font, CTkFont): elif isinstance(font, CTkFont):
return font return font.create_scaled_tuple(self._widget_scaling)
else:
raise ValueError(f"Can not scale font '{font}' of type {type(font)}. font needs to be tuple or instance of CTkFont")
def _apply_argument_scaling(self, kwargs: dict) -> dict: def _apply_argument_scaling(self, kwargs: dict) -> dict:
scaled_kwargs = copy.copy(kwargs) scaled_kwargs = copy.copy(kwargs)

View File

@ -82,10 +82,15 @@ class CTk(tkinter.Tk):
def _update_dimensions_event(self, event=None): def _update_dimensions_event(self, event=None):
if not self._block_update_dimensions_event: if not self._block_update_dimensions_event:
self.update_idletasks()
# removed this because of python stackoverflow error with many label widgets
# self.update_idletasks()
detected_width = self.winfo_width() # detect current window size detected_width = self.winfo_width() # detect current window size
detected_height = self.winfo_height() detected_height = self.winfo_height()
# detected_width = event.width
# detected_height = event.height
if self._current_width != round(detected_width / self._window_scaling) or self._current_height != round(detected_height / self._window_scaling): if self._current_width != round(detected_width / self._window_scaling) or self._current_height != round(detected_height / self._window_scaling):
self._current_width = round(detected_width / self._window_scaling) # adjust current size according to new size given by event self._current_width = round(detected_width / self._window_scaling) # adjust current size according to new size given by event
self._current_height = round(detected_height / self._window_scaling) # _current_width and _current_height are independent of the scale self._current_height = round(detected_height / self._window_scaling) # _current_width and _current_height are independent of the scale

View File

@ -138,7 +138,7 @@ class App(customtkinter.CTk):
self.seg_button_1.configure(values=["CTkSegmentedButton", "Value 2", "Value 3"]) self.seg_button_1.configure(values=["CTkSegmentedButton", "Value 2", "Value 3"])
self.seg_button_1.set("Value 2") self.seg_button_1.set("Value 2")
self.attributes("-fullscreen", True) # self.attributes("-fullscreen", True)
def open_input_dialog(self): def open_input_dialog(self):
dialog = customtkinter.CTkInputDialog(master=self, text="Type in a number:", title="CTkInputDialog") dialog = customtkinter.CTkInputDialog(master=self, text="Type in a number:", title="CTkInputDialog")

View File

@ -0,0 +1,63 @@
import customtkinter
app = customtkinter.CTk()
app.geometry("1200x1000")
app.grid_rowconfigure(0, weight=1)
app.grid_columnconfigure((0, 1), weight=1)
frame_1 = customtkinter.CTkFrame(app)
frame_1.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
frame_2 = customtkinter.CTkFrame(app)
frame_2.grid(row=0, column=1, sticky="nsew", padx=10, pady=10)
def set_scaling(scaling):
customtkinter.set_widget_scaling(scaling)
customtkinter.set_spacing_scaling(scaling)
scaling_button = customtkinter._CTkSegmentedButton(frame_1, values=[0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.5, 2.0], command=set_scaling)
scaling_button.pack(pady=(2, 10))
b = customtkinter.CTkButton(frame_1, text="single name", font=("Times", ))
b.pack(pady=2)
b = customtkinter.CTkButton(frame_1, text="name with size", font=("Times", 18))
b.pack(pady=2)
b = customtkinter.CTkButton(frame_1, text="name with negative size", font=("Times", -18))
b.pack(pady=2)
b = customtkinter.CTkButton(frame_1, text="extra keywords", font=("Times", -18, "bold italic underline overstrike"))
b.pack(pady=2)
b = customtkinter.CTkButton(frame_1, text="object default")
b.pack(pady=(10, 2))
b = customtkinter.CTkButton(frame_1, text="object single name", font=customtkinter._CTkFont("Times"))
b.pack(pady=2)
b = customtkinter.CTkButton(frame_1, text="object with name and size", font=customtkinter._CTkFont("Times", 18))
b.pack(pady=2)
b = customtkinter.CTkButton(frame_1, text="object with name and negative size", font=customtkinter._CTkFont("Times", -18))
b.pack(pady=2)
b = customtkinter.CTkButton(frame_1, text="object with extra keywords",
font=customtkinter._CTkFont("Times", -18, weight="bold", slant="italic", underline=True, overstrike=True))
b.pack(pady=2)
b1 = customtkinter.CTkButton(frame_1, text="object default modified")
b1.pack(pady=(10, 2))
b1.cget("font").configure(size=9)
print(b1.cget("font").cget("size"), b1.cget("font").cget("family"))
b2 = customtkinter.CTkButton(frame_1, text="object default overridden")
b2.pack(pady=10)
b2.configure(font=customtkinter._CTkFont(family="Times"))
label_font = customtkinter._CTkFont(size=5)
for i in range(30):
l = customtkinter.CTkLabel(frame_2, font=label_font, height=0)
l.grid(row=i, column=0)
b = customtkinter.CTkButton(frame_2, font=label_font, height=5)
b.grid(row=i, column=1, pady=2)
c = customtkinter.CTkCheckBox(frame_2, font=label_font)
c.grid(row=i, column=2, pady=2)
frame_2.grid_columnconfigure((0, 1, 2), weight=1)
app.after(1500, lambda: label_font.configure(size=10))
# app.after(1500, lambda: l.configure(text="dshgfldjskhfjdslafhdjsgkkjdaslö"))
app.mainloop()

View File

@ -23,7 +23,7 @@ b1.pack(pady=20)
b2 = customtkinter.CTkButton(master=tabview_1.tab("tab 2"), text="button tab 2") b2 = customtkinter.CTkButton(master=tabview_1.tab("tab 2"), text="button tab 2")
b2.pack() b2.pack()
tabview_1.tab("tab 2").configure(fg_color="red") # tabview_1.tab("tab 2").configure(fg_color="red")
tabview_1.configure(state="normal") tabview_1.configure(state="normal")
# tabview_1.delete("tab 1") # tabview_1.delete("tab 1")