mirror of
https://github.com/TomSchimansky/CustomTkinter.git
synced 2023-08-10 21:13:13 +03:00
added scaling to every widget
This commit is contained in:
parent
59a8574f4c
commit
6342bf8034
@ -14,9 +14,10 @@ from .widgets.ctk_canvas import CTkCanvas
|
|||||||
from .widgets.ctk_switch import CTkSwitch
|
from .widgets.ctk_switch import CTkSwitch
|
||||||
from .widgets.ctk_toplevel import CTkToplevel
|
from .widgets.ctk_toplevel import CTkToplevel
|
||||||
|
|
||||||
from .customtkinter_settings import CTkSettings
|
from .ctk_settings import CTkSettings
|
||||||
from .appearance_mode_tracker import AppearanceModeTracker
|
from .appearance_mode_tracker import AppearanceModeTracker
|
||||||
from .theme_manager import CTkThemeManager
|
from .theme_manager import CTkThemeManager
|
||||||
|
from .scaling_tracker import ScalingTracker
|
||||||
|
|
||||||
from distutils.version import StrictVersion as Version
|
from distutils.version import StrictVersion as Version
|
||||||
import tkinter
|
import tkinter
|
||||||
|
@ -2,9 +2,9 @@ import tkinter
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..customtkinter_theme_manager import CTkThemeManager
|
from ..theme_manager import CTkThemeManager
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
from ..customtkinter_draw_engine import CTkDrawEngine
|
from ..ctk_draw_engine import CTkDrawEngine
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
|
|
||||||
@ -65,8 +65,8 @@ class CTkButton(CTkBaseClass):
|
|||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
width=self.width,
|
width=self.width * self.scaling,
|
||||||
height=self.height)
|
height=self.height * self.scaling)
|
||||||
self.canvas.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="nsew")
|
self.canvas.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="nsew")
|
||||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||||
|
|
||||||
@ -75,9 +75,7 @@ class CTkButton(CTkBaseClass):
|
|||||||
self.canvas.bind("<Leave>", self.on_leave)
|
self.canvas.bind("<Leave>", self.on_leave)
|
||||||
self.canvas.bind("<Button-1>", self.clicked)
|
self.canvas.bind("<Button-1>", self.clicked)
|
||||||
self.canvas.bind("<Button-1>", self.clicked)
|
self.canvas.bind("<Button-1>", self.clicked)
|
||||||
|
self.bind('<Configure>', self.update_dimensions_event)
|
||||||
# Each time an item is resized due to pack position mode, the binding Configure is called on the widget
|
|
||||||
self.bind('<Configure>', self.update_dimensions)
|
|
||||||
|
|
||||||
self.set_cursor()
|
self.set_cursor()
|
||||||
self.draw() # initial draw
|
self.draw() # initial draw
|
||||||
@ -90,7 +88,10 @@ class CTkButton(CTkBaseClass):
|
|||||||
self.grid_columnconfigure(1, weight=1)
|
self.grid_columnconfigure(1, weight=1)
|
||||||
|
|
||||||
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.width, self.height, self.corner_radius, self.border_width)
|
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.width * self.scaling,
|
||||||
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
self.border_width * self.scaling)
|
||||||
|
|
||||||
if no_color_updates is False or requires_recoloring:
|
if no_color_updates is False or requires_recoloring:
|
||||||
|
|
||||||
@ -115,7 +116,9 @@ class CTkButton(CTkBaseClass):
|
|||||||
if self.text is not None and self.text != "":
|
if self.text is not None and self.text != "":
|
||||||
|
|
||||||
if self.text_label is None:
|
if self.text_label is None:
|
||||||
self.text_label = tkinter.Label(master=self, font=self.text_font, textvariable=self.textvariable)
|
self.text_label = tkinter.Label(master=self,
|
||||||
|
font=self.apply_font_scaling(self.text_font),
|
||||||
|
textvariable=self.textvariable)
|
||||||
|
|
||||||
self.text_label.bind("<Enter>", self.on_enter)
|
self.text_label.bind("<Enter>", self.on_enter)
|
||||||
self.text_label.bind("<Leave>", self.on_leave)
|
self.text_label.bind("<Leave>", self.on_leave)
|
||||||
@ -172,26 +175,35 @@ class CTkButton(CTkBaseClass):
|
|||||||
|
|
||||||
# create grid layout with just an image given
|
# create grid layout with just an image given
|
||||||
if self.image_label is not None and self.text_label is None:
|
if self.image_label is not None and self.text_label is None:
|
||||||
self.image_label.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="", pady=self.border_width)
|
self.image_label.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="", pady=self.border_width * self.scaling)
|
||||||
|
|
||||||
# create grid layout with just text given
|
# create grid layout with just text given
|
||||||
if self.image_label is None and self.text_label is not None:
|
if self.image_label is None and self.text_label is not None:
|
||||||
self.text_label.grid(row=0, column=0, padx=self.corner_radius, pady=self.border_width, rowspan=2, columnspan=2, sticky="")
|
self.text_label.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="",
|
||||||
|
padx=self.corner_radius * self.scaling, pady=self.border_width * self.scaling)
|
||||||
|
|
||||||
# create grid layout of image and text label in 2x2 grid system with given compound
|
# create grid layout of image and text label in 2x2 grid system with given compound
|
||||||
if self.image_label is not None and self.text_label is not None:
|
if self.image_label is not None and self.text_label is not None:
|
||||||
if self.compound == tkinter.LEFT or self.compound == "left":
|
if self.compound == tkinter.LEFT or self.compound == "left":
|
||||||
self.image_label.grid(row=0, column=0, padx=(max(self.corner_radius, self.border_width), 2), sticky="e", rowspan=2, columnspan=1, pady=self.border_width)
|
self.image_label.grid(row=0, column=0, sticky="e", rowspan=2, columnspan=1,
|
||||||
self.text_label.grid(row=0, column=1, padx=(2, max(self.corner_radius, self.border_width)), sticky="w", rowspan=2, columnspan=1, pady=self.border_width)
|
padx=(max(self.corner_radius * self.scaling, self.border_width * self.scaling), 2), pady=self.border_width * self.scaling)
|
||||||
|
self.text_label.grid(row=0, column=1, sticky="w", rowspan=2, columnspan=1,
|
||||||
|
padx=(2, max(self.corner_radius * self.scaling, self.border_width * self.scaling)), pady=self.border_width * self.scaling)
|
||||||
elif self.compound == tkinter.TOP or self.compound == "top":
|
elif self.compound == tkinter.TOP or self.compound == "top":
|
||||||
self.image_label.grid(row=0, column=0, padx=max(self.corner_radius, self.border_width), sticky="s", columnspan=2, rowspan=1, pady=(self.border_width, 2))
|
self.image_label.grid(row=0, column=0, sticky="s", columnspan=2, rowspan=1,
|
||||||
self.text_label.grid(row=1, column=0, padx=max(self.corner_radius, self.border_width), sticky="n", columnspan=2, rowspan=1, pady=(2, self.border_width))
|
padx=max(self.corner_radius * self.scaling, self.border_width * self.scaling), pady=(self.border_width * self.scaling, 2))
|
||||||
|
self.text_label.grid(row=1, column=0, sticky="n", columnspan=2, rowspan=1,
|
||||||
|
padx=max(self.corner_radius * self.scaling, self.border_width * self.scaling), pady=(2, self.border_width * self.scaling))
|
||||||
elif self.compound == tkinter.RIGHT or self.compound == "right":
|
elif self.compound == tkinter.RIGHT or self.compound == "right":
|
||||||
self.image_label.grid(row=0, column=1, padx=(2, max(self.corner_radius, self.border_width)), sticky="w", rowspan=2, columnspan=1, pady=self.border_width)
|
self.image_label.grid(row=0, column=1, sticky="w", rowspan=2, columnspan=1,
|
||||||
self.text_label.grid(row=0, column=0, padx=(max(self.corner_radius, self.border_width), 2), sticky="e", rowspan=2, columnspan=1, pady=self.border_width)
|
padx=(2, max(self.corner_radius * self.scaling, self.border_width * self.scaling)), pady=self.border_width * self.scaling)
|
||||||
|
self.text_label.grid(row=0, column=0, sticky="e", rowspan=2, columnspan=1,
|
||||||
|
padx=(max(self.corner_radius * self.scaling, self.border_width * self.scaling), 2), pady=self.border_width * self.scaling)
|
||||||
elif self.compound == tkinter.BOTTOM or self.compound == "bottom":
|
elif self.compound == tkinter.BOTTOM or self.compound == "bottom":
|
||||||
self.image_label.grid(row=1, column=0, padx=max(self.corner_radius, self.border_width), sticky="n", columnspan=2, rowspan=1, pady=(2, self.border_width))
|
self.image_label.grid(row=1, column=0, sticky="n", columnspan=2, rowspan=1,
|
||||||
self.text_label.grid(row=0, column=0, padx=max(self.corner_radius, self.border_width), sticky="s", columnspan=2, rowspan=1, pady=(self.border_width, 2))
|
padx=max(self.corner_radius * self.scaling, self.border_width * self.scaling), pady=(2, self.border_width * self.scaling))
|
||||||
|
self.text_label.grid(row=0, column=0, sticky="s", columnspan=2, rowspan=1,
|
||||||
|
padx=max(self.corner_radius * self.scaling, self.border_width * self.scaling), pady=(self.border_width * self.scaling, 2))
|
||||||
|
|
||||||
def configure(self, *args, **kwargs):
|
def configure(self, *args, **kwargs):
|
||||||
require_redraw = False # some attribute changes require a call of self.draw() at the end
|
require_redraw = False # some attribute changes require a call of self.draw() at the end
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import tkinter
|
import tkinter
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
|
|
||||||
|
|
||||||
class CTkCanvas(tkinter.Canvas):
|
class CTkCanvas(tkinter.Canvas):
|
||||||
|
@ -2,9 +2,9 @@ import tkinter
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..customtkinter_theme_manager import CTkThemeManager
|
from ..theme_manager import CTkThemeManager
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
from ..customtkinter_draw_engine import CTkDrawEngine
|
from ..ctk_draw_engine import CTkDrawEngine
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
|
|
||||||
@ -68,14 +68,15 @@ class CTkCheckBox(CTkBaseClass):
|
|||||||
|
|
||||||
# configure grid system (1x3)
|
# configure grid system (1x3)
|
||||||
self.grid_columnconfigure(0, weight=0)
|
self.grid_columnconfigure(0, weight=0)
|
||||||
self.grid_columnconfigure(1, weight=0, minsize=6)
|
self.grid_columnconfigure(1, weight=0, minsize=6 * self.scaling)
|
||||||
self.grid_columnconfigure(2, weight=1)
|
self.grid_columnconfigure(2, weight=1)
|
||||||
|
self.grid_rowconfigure(0, weight=1)
|
||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
width=self.width,
|
width=self.width * self.scaling,
|
||||||
height=self.height)
|
height=self.height * self.scaling)
|
||||||
self.canvas.grid(row=0, column=0, padx=0, pady=0, columnspan=1)
|
self.canvas.grid(row=0, column=0, padx=0, pady=0, columnspan=1, rowspan=1)
|
||||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||||
|
|
||||||
if self.hover is True:
|
if self.hover is True:
|
||||||
@ -103,15 +104,20 @@ class CTkCheckBox(CTkBaseClass):
|
|||||||
super().destroy()
|
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.width, self.height, self.corner_radius, self.border_width)
|
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.width * self.scaling,
|
||||||
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
self.border_width * self.scaling)
|
||||||
|
|
||||||
if self.check_state is True:
|
if self.check_state is True:
|
||||||
self.draw_engine.draw_checkmark(self.width, self.height, self.height * 0.58)
|
self.draw_engine.draw_checkmark(self.width * self.scaling,
|
||||||
|
self.height * self.scaling,
|
||||||
|
self.height * 0.58 * self.scaling)
|
||||||
else:
|
else:
|
||||||
self.canvas.delete("checkmark")
|
self.canvas.delete("checkmark")
|
||||||
|
|
||||||
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
|
||||||
self.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
self.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
|
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
|
|
||||||
if self.check_state is True:
|
if self.check_state is True:
|
||||||
self.canvas.itemconfig("inner_parts",
|
self.canvas.itemconfig("inner_parts",
|
||||||
@ -134,11 +140,12 @@ class CTkCheckBox(CTkBaseClass):
|
|||||||
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
|
fill=CTkThemeManager.single_color(self.border_color, self.appearance_mode))
|
||||||
|
|
||||||
if self.text_label is None:
|
if self.text_label is None:
|
||||||
|
print("create label")
|
||||||
self.text_label = tkinter.Label(master=self,
|
self.text_label = tkinter.Label(master=self,
|
||||||
bd=0,
|
bd=0,
|
||||||
text=self.text,
|
text=self.text,
|
||||||
justify=tkinter.LEFT,
|
justify=tkinter.LEFT,
|
||||||
font=self.text_font)
|
font=self.apply_font_scaling(self.text_font))
|
||||||
self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w")
|
self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w")
|
||||||
self.text_label["anchor"] = "w"
|
self.text_label["anchor"] = "w"
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import tkinter
|
import tkinter
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..customtkinter_theme_manager import CTkThemeManager
|
from ..theme_manager import CTkThemeManager
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
from ..customtkinter_draw_engine import CTkDrawEngine
|
from ..ctk_draw_engine import CTkDrawEngine
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
|
|
||||||
@ -46,8 +46,8 @@ class CTkEntry(CTkBaseClass):
|
|||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
width=self.width,
|
width=self.width * self.scaling,
|
||||||
height=self.height)
|
height=self.height * self.scaling)
|
||||||
self.canvas.grid(column=0, row=0, sticky="we")
|
self.canvas.grid(column=0, row=0, sticky="we")
|
||||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||||
|
|
||||||
@ -55,11 +55,12 @@ class CTkEntry(CTkBaseClass):
|
|||||||
bd=0,
|
bd=0,
|
||||||
width=1,
|
width=1,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
font=self.text_font,
|
font=self.apply_font_scaling(self.text_font),
|
||||||
**kwargs)
|
**kwargs)
|
||||||
self.entry.grid(column=0, row=0, sticky="we", padx=self.corner_radius if self.corner_radius >= 6 else 6)
|
self.entry.grid(column=0, row=0, sticky="we",
|
||||||
|
padx=self.corner_radius * self.scaling if self.corner_radius >= 6 * self.scaling else 6 * self.scaling)
|
||||||
|
|
||||||
super().bind('<Configure>', self.update_dimensions)
|
super().bind('<Configure>', self.update_dimensions_event)
|
||||||
self.entry.bind('<FocusOut>', self.set_placeholder)
|
self.entry.bind('<FocusOut>', self.set_placeholder)
|
||||||
self.entry.bind('<FocusIn>', self.clear_placeholder)
|
self.entry.bind('<FocusIn>', self.clear_placeholder)
|
||||||
|
|
||||||
@ -90,7 +91,10 @@ class CTkEntry(CTkBaseClass):
|
|||||||
def draw(self, no_color_updates=False):
|
def draw(self, no_color_updates=False):
|
||||||
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
|
|
||||||
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.width, self.height, self.corner_radius, self.border_width)
|
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.width * self.scaling,
|
||||||
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
self.border_width * self.scaling)
|
||||||
|
|
||||||
if CTkThemeManager.single_color(self.fg_color, self.appearance_mode) is not None:
|
if CTkThemeManager.single_color(self.fg_color, self.appearance_mode) is not None:
|
||||||
self.canvas.itemconfig("inner_parts",
|
self.canvas.itemconfig("inner_parts",
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import tkinter
|
import tkinter
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..customtkinter_theme_manager import CTkThemeManager
|
from ..theme_manager import CTkThemeManager
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
from ..customtkinter_draw_engine import CTkDrawEngine
|
from ..ctk_draw_engine import CTkDrawEngine
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
|
|
||||||
@ -41,13 +41,13 @@ class CTkFrame(CTkBaseClass):
|
|||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
width=self.width,
|
width=self.width * self.scaling,
|
||||||
height=self.height)
|
height=self.height * self.scaling)
|
||||||
self.canvas.place(x=0, y=0, relwidth=1, relheight=1)
|
self.canvas.place(x=0, y=0, relwidth=1, relheight=1)
|
||||||
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||||
|
|
||||||
self.bind('<Configure>', self.update_dimensions)
|
self.bind('<Configure>', self.update_dimensions_event)
|
||||||
|
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
@ -64,7 +64,10 @@ class CTkFrame(CTkBaseClass):
|
|||||||
|
|
||||||
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.width, self.height, self.corner_radius, self.border_width)
|
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.width * self.scaling,
|
||||||
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
self.border_width * self.scaling)
|
||||||
|
|
||||||
if no_color_updates is False or requires_recoloring:
|
if no_color_updates is False or requires_recoloring:
|
||||||
self.canvas.itemconfig("inner_parts",
|
self.canvas.itemconfig("inner_parts",
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import tkinter
|
import tkinter
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..customtkinter_theme_manager import CTkThemeManager
|
from ..theme_manager import CTkThemeManager
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
from ..customtkinter_draw_engine import CTkDrawEngine
|
from ..ctk_draw_engine import CTkDrawEngine
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
|
|
||||||
@ -45,8 +45,8 @@ class CTkLabel(CTkBaseClass):
|
|||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
width=self.width,
|
width=self.width * self.scaling,
|
||||||
height=self.height)
|
height=self.height * self.scaling)
|
||||||
self.canvas.grid(row=0, column=0, sticky="nswe")
|
self.canvas.grid(row=0, column=0, sticky="nswe")
|
||||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||||
|
|
||||||
@ -54,15 +54,18 @@ class CTkLabel(CTkBaseClass):
|
|||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
bd=0,
|
bd=0,
|
||||||
text=self.text,
|
text=self.text,
|
||||||
font=self.text_font,
|
font=self.apply_font_scaling(self.text_font),
|
||||||
**kwargs)
|
**kwargs)
|
||||||
self.text_label.grid(row=0, column=0, padx=self.corner_radius)
|
self.text_label.grid(row=0, column=0, padx=self.corner_radius)
|
||||||
|
|
||||||
self.bind('<Configure>', self.update_dimensions)
|
self.bind('<Configure>', self.update_dimensions_event)
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
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.width, self.height, self.corner_radius, 0)
|
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.width * self.scaling,
|
||||||
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
0)
|
||||||
|
|
||||||
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import tkinter
|
import tkinter
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..customtkinter_theme_manager import CTkThemeManager
|
from ..theme_manager import CTkThemeManager
|
||||||
from ..customtkinter_draw_engine import CTkDrawEngine
|
from ..ctk_draw_engine import CTkDrawEngine
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
|
|
||||||
@ -40,15 +40,18 @@ class CTkProgressBar(CTkBaseClass):
|
|||||||
self.border_width = CTkThemeManager.theme["shape"]["progressbar_border_width"] if border_width == "default_theme" else border_width
|
self.border_width = CTkThemeManager.theme["shape"]["progressbar_border_width"] if border_width == "default_theme" else border_width
|
||||||
self.value = 0.5
|
self.value = 0.5
|
||||||
|
|
||||||
|
self.grid_rowconfigure(1, weight=1)
|
||||||
|
self.grid_columnconfigure(1, weight=1)
|
||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
width=self.width,
|
width=self.width * self.scaling,
|
||||||
height=self.height)
|
height=self.height * self.scaling)
|
||||||
self.canvas.place(x=0, y=0, relwidth=1, relheight=1)
|
self.canvas.grid(row=0, column=0, rowspan=1, columnspan=1)
|
||||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||||
|
|
||||||
# Each time an item is resized due to pack position mode, the binding Configure is called on the widget
|
# Each time an item is resized due to pack position mode, the binding Configure is called on the widget
|
||||||
self.bind('<Configure>', self.update_dimensions)
|
self.bind('<Configure>', self.update_dimensions_event)
|
||||||
|
|
||||||
self.draw() # initial draw
|
self.draw() # initial draw
|
||||||
|
|
||||||
@ -65,8 +68,13 @@ class CTkProgressBar(CTkBaseClass):
|
|||||||
super().destroy()
|
super().destroy()
|
||||||
|
|
||||||
def draw(self, no_color_updates=False):
|
def draw(self, no_color_updates=False):
|
||||||
|
print("progress", self.scaling)
|
||||||
|
|
||||||
requires_recoloring = self.draw_engine.draw_rounded_progress_bar_with_border(self.width, self.height, self.corner_radius, self.border_width, self.value, "w")
|
requires_recoloring = self.draw_engine.draw_rounded_progress_bar_with_border(self.width * self.scaling,
|
||||||
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
self.border_width * self.scaling,
|
||||||
|
self.value, "w")
|
||||||
|
|
||||||
if no_color_updates is False or requires_recoloring:
|
if no_color_updates is False or requires_recoloring:
|
||||||
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
|
@ -2,9 +2,9 @@ import tkinter
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..customtkinter_theme_manager import CTkThemeManager
|
from ..theme_manager import CTkThemeManager
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
from ..customtkinter_draw_engine import CTkDrawEngine
|
from ..ctk_draw_engine import CTkDrawEngine
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
|
|
||||||
@ -65,13 +65,13 @@ class CTkRadioButton(CTkBaseClass):
|
|||||||
|
|
||||||
# configure grid system (3x1)
|
# configure grid system (3x1)
|
||||||
self.grid_columnconfigure(0, weight=0)
|
self.grid_columnconfigure(0, weight=0)
|
||||||
self.grid_columnconfigure(1, weight=0, minsize=6)
|
self.grid_columnconfigure(1, weight=0, minsize=6 * self.scaling)
|
||||||
self.grid_columnconfigure(2, weight=1)
|
self.grid_columnconfigure(2, weight=1)
|
||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
width=self.width,
|
width=self.width * self.scaling,
|
||||||
height=self.height)
|
height=self.height * self.scaling)
|
||||||
self.canvas.grid(row=0, column=0, padx=0, pady=0, columnspan=1)
|
self.canvas.grid(row=0, column=0, padx=0, pady=0, columnspan=1)
|
||||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||||
|
|
||||||
@ -97,7 +97,10 @@ class CTkRadioButton(CTkBaseClass):
|
|||||||
super().destroy()
|
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.width, self.height, self.corner_radius, self.border_width)
|
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.width * self.scaling,
|
||||||
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
self.border_width * self.scaling)
|
||||||
|
|
||||||
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
self.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
self.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
@ -120,7 +123,7 @@ class CTkRadioButton(CTkBaseClass):
|
|||||||
bd=0,
|
bd=0,
|
||||||
text=self.text,
|
text=self.text,
|
||||||
justify=tkinter.LEFT,
|
justify=tkinter.LEFT,
|
||||||
font=self.text_font)
|
font=self.apply_font_scaling(self.text_font))
|
||||||
self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w")
|
self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w")
|
||||||
self.text_label["anchor"] = "w"
|
self.text_label["anchor"] = "w"
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ import tkinter
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..customtkinter_theme_manager import CTkThemeManager
|
from ..theme_manager import CTkThemeManager
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
from ..customtkinter_draw_engine import CTkDrawEngine
|
from ..ctk_draw_engine import CTkDrawEngine
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
|
|
||||||
@ -64,8 +64,8 @@ class CTkSlider(CTkBaseClass):
|
|||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
width=self.width,
|
width=self.width * self.scaling,
|
||||||
height=self.height)
|
height=self.height * self.scaling)
|
||||||
self.canvas.grid(column=0, row=0, sticky="nswe")
|
self.canvas.grid(column=0, row=0, sticky="nswe")
|
||||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ class CTkSlider(CTkBaseClass):
|
|||||||
self.canvas.bind("<B1-Motion>", self.clicked)
|
self.canvas.bind("<B1-Motion>", self.clicked)
|
||||||
|
|
||||||
# Each time an item is resized due to pack position mode, the binding Configure is called on the widget
|
# Each time an item is resized due to pack position mode, the binding Configure is called on the widget
|
||||||
self.bind('<Configure>', self.update_dimensions)
|
self.bind('<Configure>', self.update_dimensions_event)
|
||||||
|
|
||||||
self.set_cursor()
|
self.set_cursor()
|
||||||
self.draw() # initial draw
|
self.draw() # initial draw
|
||||||
@ -104,8 +104,13 @@ class CTkSlider(CTkBaseClass):
|
|||||||
self.configure(cursor="hand2")
|
self.configure(cursor="hand2")
|
||||||
|
|
||||||
def draw(self, no_color_updates=False):
|
def draw(self, no_color_updates=False):
|
||||||
requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width, self.height, self.corner_radius, self.border_width,
|
requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width * self.scaling,
|
||||||
self.button_length, self.button_corner_radius, self.value, "w")
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
self.border_width * self.scaling,
|
||||||
|
self.button_length * self.scaling,
|
||||||
|
self.button_corner_radius * self.scaling,
|
||||||
|
self.value, "w")
|
||||||
|
|
||||||
if no_color_updates is False or requires_recoloring:
|
if no_color_updates is False or requires_recoloring:
|
||||||
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
@ -131,7 +136,7 @@ class CTkSlider(CTkBaseClass):
|
|||||||
outline=CTkThemeManager.single_color(self.button_color, self.appearance_mode))
|
outline=CTkThemeManager.single_color(self.button_color, self.appearance_mode))
|
||||||
|
|
||||||
def clicked(self, event=None):
|
def clicked(self, event=None):
|
||||||
self.value = event.x / self.width
|
self.value = (event.x / self.width) / self.scaling
|
||||||
|
|
||||||
if self.value > 1:
|
if self.value > 1:
|
||||||
self.value = 1
|
self.value = 1
|
||||||
|
@ -2,9 +2,9 @@ import tkinter
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..customtkinter_theme_manager import CTkThemeManager
|
from ..theme_manager import CTkThemeManager
|
||||||
from ..customtkinter_settings import CTkSettings
|
from ..ctk_settings import CTkSettings
|
||||||
from ..customtkinter_draw_engine import CTkDrawEngine
|
from ..ctk_draw_engine import CTkDrawEngine
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
|
|
||||||
@ -70,13 +70,13 @@ class CTkSwitch(CTkBaseClass):
|
|||||||
|
|
||||||
# configure grid system (3x1)
|
# configure grid system (3x1)
|
||||||
self.grid_columnconfigure(0, weight=1)
|
self.grid_columnconfigure(0, weight=1)
|
||||||
self.grid_columnconfigure(1, weight=0, minsize=6)
|
self.grid_columnconfigure(1, weight=0, minsize=6 * self.scaling)
|
||||||
self.grid_columnconfigure(2, weight=0)
|
self.grid_columnconfigure(2, weight=0)
|
||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
width=self.width,
|
width=self.width * self.scaling,
|
||||||
height=self.height)
|
height=self.height * self.scaling)
|
||||||
self.canvas.grid(row=0, column=0, padx=0, pady=0, columnspan=1, sticky="nswe")
|
self.canvas.grid(row=0, column=0, padx=0, pady=0, columnspan=1, sticky="nswe")
|
||||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||||
|
|
||||||
@ -110,11 +110,21 @@ class CTkSwitch(CTkBaseClass):
|
|||||||
def draw(self, no_color_updates=False):
|
def draw(self, no_color_updates=False):
|
||||||
|
|
||||||
if self.check_state is True:
|
if self.check_state is True:
|
||||||
requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width, self.height, self.corner_radius, self.border_width,
|
requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width * self.scaling,
|
||||||
self.button_length, self.corner_radius, 1, "w")
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
self.border_width * self.scaling,
|
||||||
|
self.button_length * self.scaling,
|
||||||
|
self.corner_radius * self.scaling
|
||||||
|
, 1, "w")
|
||||||
else:
|
else:
|
||||||
requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width, self.height, self.corner_radius, self.border_width,
|
requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width * self.scaling,
|
||||||
self.button_length, self.corner_radius, 0, "w")
|
self.height * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
self.border_width * self.scaling,
|
||||||
|
self.button_length * self.scaling,
|
||||||
|
self.corner_radius * self.scaling,
|
||||||
|
0, "w")
|
||||||
|
|
||||||
if no_color_updates is False or requires_recoloring:
|
if no_color_updates is False or requires_recoloring:
|
||||||
self.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
self.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
@ -145,7 +155,7 @@ class CTkSwitch(CTkBaseClass):
|
|||||||
bd=0,
|
bd=0,
|
||||||
text=self.text,
|
text=self.text,
|
||||||
justify=tkinter.LEFT,
|
justify=tkinter.LEFT,
|
||||||
font=self.text_font)
|
font=self.apply_font_scaling(self.text_font))
|
||||||
self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w")
|
self.text_label.grid(row=0, column=2, padx=0, pady=0, sticky="w")
|
||||||
self.text_label["anchor"] = "w"
|
self.text_label["anchor"] = "w"
|
||||||
if self.textvariable is not None:
|
if self.textvariable is not None:
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import tkinter
|
import tkinter
|
||||||
import tkinter.ttk as ttk
|
import tkinter.ttk as ttk
|
||||||
|
import copy
|
||||||
|
import re
|
||||||
|
|
||||||
from .ctk_tk import CTk
|
from .ctk_tk import CTk
|
||||||
from .ctk_toplevel import CTkToplevel
|
from .ctk_toplevel import CTkToplevel
|
||||||
from ..appearance_mode_tracker import AppearanceModeTracker
|
from ..appearance_mode_tracker import AppearanceModeTracker
|
||||||
|
from ..scaling_tracker import ScalingTracker
|
||||||
|
from ..theme_manager import CTkThemeManager
|
||||||
|
|
||||||
|
|
||||||
class CTkBaseClass(tkinter.Frame):
|
class CTkBaseClass(tkinter.Frame):
|
||||||
@ -12,12 +16,18 @@ class CTkBaseClass(tkinter.Frame):
|
|||||||
|
|
||||||
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
|
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
|
||||||
self.width = width # width and height in pixel, represent current size of the widget (not the desired size by init)
|
self.width = width # width and height in pixel, represent current size of the widget (not the desired size by init)
|
||||||
self.height = height
|
self.height = height # width and height are independent of the scale
|
||||||
|
|
||||||
|
# add set_scaling method to callback list of ScalingTracker for automatic scaling changes
|
||||||
|
ScalingTracker.add_widget(self.set_scaling, self)
|
||||||
|
self.scaling = ScalingTracker.get_widget_scaling(self)
|
||||||
|
|
||||||
# add set_appearance_mode method to callback list of AppearanceModeTracker for appearance mode changes
|
# add set_appearance_mode method to callback list of AppearanceModeTracker for appearance mode changes
|
||||||
AppearanceModeTracker.add(self.set_appearance_mode, self)
|
AppearanceModeTracker.add(self.set_appearance_mode, self)
|
||||||
self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
|
self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
|
||||||
|
|
||||||
|
super().configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||||
|
|
||||||
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget too
|
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget too
|
||||||
if isinstance(self.master, (tkinter.Tk, tkinter.Toplevel, tkinter.Frame)) and not isinstance(self.master, (CTkBaseClass, CTk, CTkToplevel)):
|
if isinstance(self.master, (tkinter.Tk, tkinter.Toplevel, tkinter.Frame)) and not isinstance(self.master, (CTkBaseClass, CTk, CTkToplevel)):
|
||||||
master_old_configure = self.master.config
|
master_old_configure = self.master.config
|
||||||
@ -64,11 +74,11 @@ class CTkBaseClass(tkinter.Frame):
|
|||||||
if require_redraw:
|
if require_redraw:
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def update_dimensions(self, event):
|
def update_dimensions_event(self, event):
|
||||||
# only redraw if dimensions changed (for performance)
|
# only redraw if dimensions changed (for performance)
|
||||||
if self.width != event.width or self.height != event.height:
|
if self.width != int(event.width * self.scaling) or self.height != int(event.height * self.scaling):
|
||||||
self.width = event.width # adjust current size according to new size given by event
|
self.width = int(event.width / self.scaling) # adjust current size according to new size given by event
|
||||||
self.height = event.height
|
self.height = int(event.height / self.scaling) # width and height are independent of the scale
|
||||||
|
|
||||||
self.draw(no_color_updates=True) # faster drawing without color changes
|
self.draw(no_color_updates=True) # faster drawing without color changes
|
||||||
|
|
||||||
@ -104,6 +114,33 @@ class CTkBaseClass(tkinter.Frame):
|
|||||||
|
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
|
def set_scaling(self, new_scaling):
|
||||||
|
self.scaling = new_scaling
|
||||||
|
|
||||||
|
super().configure(width=self.width * self.scaling, height=self.height * self.scaling)
|
||||||
|
|
||||||
|
def apply_font_scaling(self, font):
|
||||||
|
if type(font) == tuple or type(font) == list:
|
||||||
|
font_list = list(font)
|
||||||
|
for i in range(len(font_list)):
|
||||||
|
if (type(font_list[i]) == int or type(font_list[i]) == float) and font_list[i] < 0:
|
||||||
|
font_list[i] = int(font_list[i] * self.scaling)
|
||||||
|
return tuple(font_list)
|
||||||
|
|
||||||
|
elif type(font) == str:
|
||||||
|
for negative_number in re.findall(r" -\d* ", font):
|
||||||
|
font = font.replace(negative_number, f" {int(int(negative_number) * self.scaling)} ")
|
||||||
|
return font
|
||||||
|
|
||||||
|
elif isinstance(font, tkinter.font.Font):
|
||||||
|
new_font_object = copy.copy(font)
|
||||||
|
if font.cget("size") < 0:
|
||||||
|
new_font_object.config(size=int(font.cget("size") * self.scaling))
|
||||||
|
return new_font_object
|
||||||
|
|
||||||
|
else:
|
||||||
|
return font
|
||||||
|
|
||||||
def draw(self, no_color_updates=False):
|
def draw(self, no_color_updates=False):
|
||||||
""" abstract of draw method to be overridden """
|
""" abstract of draw method to be overridden """
|
||||||
pass
|
pass
|
||||||
|
@ -4,6 +4,8 @@ import customtkinter # <- import the CustomTkinter module
|
|||||||
customtkinter.set_appearance_mode("dark") # Modes: "System" (standard), "Dark", "Light"
|
customtkinter.set_appearance_mode("dark") # Modes: "System" (standard), "Dark", "Light"
|
||||||
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
|
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
|
||||||
|
|
||||||
|
customtkinter.ScalingTracker.set_user_scaling(0.9)
|
||||||
|
|
||||||
root_tk = customtkinter.CTk() # create CTk window like you do with the Tk window (you can also use normal tkinter.Tk window)
|
root_tk = customtkinter.CTk() # create CTk window like you do with the Tk window (you can also use normal tkinter.Tk window)
|
||||||
root_tk.geometry("400x480")
|
root_tk.geometry("400x480")
|
||||||
root_tk.title("CustomTkinter Test")
|
root_tk.title("CustomTkinter Test")
|
||||||
|
Loading…
Reference in New Issue
Block a user