mirror of
https://github.com/TomSchimansky/CustomTkinter.git
synced 2023-08-10 21:13:13 +03:00
fixed small scaling issues
This commit is contained in:
parent
d36cf416b7
commit
b99f384241
@ -66,8 +66,8 @@ class CTkButton(CTkBaseClass):
|
||||
|
||||
self.canvas = CTkCanvas(master=self,
|
||||
highlightthickness=0,
|
||||
width=self.round_size(self.apply_widget_scaling(self.desired_width)),
|
||||
height=self.round_size(self.apply_widget_scaling(self.desired_height)))
|
||||
width=self.apply_widget_scaling(self.desired_width),
|
||||
height=self.apply_widget_scaling(self.desired_height))
|
||||
self.canvas.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="nsew")
|
||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||
|
||||
@ -98,8 +98,8 @@ class CTkButton(CTkBaseClass):
|
||||
self.image_label.destroy()
|
||||
self.image_label = None
|
||||
|
||||
self.canvas.configure(width=self.round_size(self.apply_widget_scaling(self.desired_width)),
|
||||
height=self.round_size(self.apply_widget_scaling(self.desired_height)))
|
||||
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
|
||||
height=self.apply_widget_scaling(self.desired_height)),
|
||||
self.draw()
|
||||
|
||||
def draw(self, no_color_updates=False):
|
||||
@ -190,37 +190,45 @@ class CTkButton(CTkBaseClass):
|
||||
|
||||
# create grid layout with just an image given
|
||||
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.apply_widget_scaling(self.border_width))
|
||||
self.image_label.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="",
|
||||
pady=(self.apply_widget_scaling(self.border_width), self.apply_widget_scaling(self.border_width) + 1)) # bottom pady with +1 for rounding to even
|
||||
|
||||
# create grid layout with just text given
|
||||
if self.image_label is None and self.text_label is not None:
|
||||
self.text_label.grid(row=0, column=0, rowspan=2, columnspan=2, sticky="",
|
||||
padx=self.apply_widget_scaling(self.corner_radius), pady=self.apply_widget_scaling(self.border_width) + 1)
|
||||
padx=self.apply_widget_scaling(self.corner_radius),
|
||||
pady=(self.apply_widget_scaling(self.border_width), self.apply_widget_scaling(self.border_width) + 1)) # bottom pady with +1 for rounding to even
|
||||
|
||||
# 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.compound == tkinter.LEFT or self.compound == "left":
|
||||
self.image_label.grid(row=0, column=0, sticky="e", rowspan=2, columnspan=1,
|
||||
padx=(max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)), 2), pady=self.apply_widget_scaling(self.border_width))
|
||||
padx=(max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)), 2),
|
||||
pady=(self.apply_widget_scaling(self.border_width), self.apply_widget_scaling(self.border_width) + 1))
|
||||
self.text_label.grid(row=0, column=1, sticky="w", rowspan=2, columnspan=1,
|
||||
padx=(2, max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width))), pady=self.apply_widget_scaling(self.border_width))
|
||||
padx=(2, max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width))),
|
||||
pady=(self.apply_widget_scaling(self.border_width), self.apply_widget_scaling(self.border_width) + 1))
|
||||
elif self.compound == tkinter.TOP or self.compound == "top":
|
||||
self.image_label.grid(row=0, column=0, sticky="s", columnspan=2, rowspan=1,
|
||||
padx=max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)), pady=(self.apply_widget_scaling(self.border_width), 2))
|
||||
padx=max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)),
|
||||
pady=(self.apply_widget_scaling(self.border_width), 2))
|
||||
self.text_label.grid(row=1, column=0, sticky="n", columnspan=2, rowspan=1,
|
||||
padx=max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)), pady=(2, self.apply_widget_scaling(self.border_width)))
|
||||
padx=max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)),
|
||||
pady=(2, self.apply_widget_scaling(self.border_width)))
|
||||
elif self.compound == tkinter.RIGHT or self.compound == "right":
|
||||
self.image_label.grid(row=0, column=1, sticky="w", rowspan=2, columnspan=1,
|
||||
padx=(2, max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width))), pady=self.apply_widget_scaling(self.border_width))
|
||||
padx=(2, max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width))),
|
||||
pady=(self.apply_widget_scaling(self.border_width), self.apply_widget_scaling(self.border_width) + 1))
|
||||
self.text_label.grid(row=0, column=0, sticky="e", rowspan=2, columnspan=1,
|
||||
padx=(max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)), 2), pady=self.apply_widget_scaling(self.border_width))
|
||||
padx=(max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)), 2),
|
||||
pady=(self.apply_widget_scaling(self.border_width), self.apply_widget_scaling(self.border_width) + 1))
|
||||
elif self.compound == tkinter.BOTTOM or self.compound == "bottom":
|
||||
self.image_label.grid(row=1, column=0, sticky="n", columnspan=2, rowspan=1,
|
||||
padx=max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)), pady=(2, self.apply_widget_scaling(self.border_width)))
|
||||
padx=max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)),
|
||||
pady=(2, self.apply_widget_scaling(self.border_width)))
|
||||
self.text_label.grid(row=0, column=0, sticky="s", columnspan=2, rowspan=1,
|
||||
padx=max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)), pady=(self.apply_widget_scaling(self.border_width), 2))
|
||||
|
||||
# self.canvas.configure(bg="red") # test
|
||||
padx=max(self.apply_widget_scaling(self.corner_radius), self.apply_widget_scaling(self.border_width)),
|
||||
pady=(self.apply_widget_scaling(self.border_width), 2))
|
||||
|
||||
def configure(self, *args, **kwargs):
|
||||
require_redraw = False # some attribute changes require a call of self.draw() at the end
|
||||
|
@ -29,7 +29,8 @@ class CTkEntry(CTkBaseClass):
|
||||
else:
|
||||
super().__init__(*args, bg_color=bg_color, width=width, height=height)
|
||||
|
||||
self.configure_basic_grid()
|
||||
self.grid_rowconfigure(0, weight=1)
|
||||
self.grid_columnconfigure(0, weight=1)
|
||||
|
||||
self.fg_color = CTkThemeManager.theme["color"]["entry"] if fg_color == "default_theme" else fg_color
|
||||
self.text_color = CTkThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
|
||||
@ -77,10 +78,6 @@ class CTkEntry(CTkBaseClass):
|
||||
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width), height=self.apply_widget_scaling(self.desired_height))
|
||||
self.draw()
|
||||
|
||||
def configure_basic_grid(self):
|
||||
self.grid_rowconfigure(0, weight=1)
|
||||
self.grid_columnconfigure(0, weight=1)
|
||||
|
||||
def set_placeholder(self, event=None):
|
||||
if self.placeholder_text is not None:
|
||||
if not self.placeholder_text_active and self.entry.get() == "":
|
||||
@ -154,6 +151,11 @@ class CTkEntry(CTkBaseClass):
|
||||
del kwargs["text_color"]
|
||||
require_redraw = True
|
||||
|
||||
if "border_color" in kwargs:
|
||||
self.border_color = kwargs["border_color"]
|
||||
del kwargs["border_color"]
|
||||
require_redraw = True
|
||||
|
||||
if "corner_radius" in kwargs:
|
||||
self.corner_radius = kwargs["corner_radius"]
|
||||
|
||||
|
@ -28,8 +28,8 @@ class CTkBaseClass(tkinter.Frame):
|
||||
self.widget_scaling = ScalingTracker.get_widget_scaling(self)
|
||||
self.spacing_scaling = ScalingTracker.get_spacing_scaling(self)
|
||||
|
||||
super().configure(width=self.round_size(self.apply_widget_scaling(self.desired_width)),
|
||||
height=self.round_size(self.apply_widget_scaling(self.desired_height)))
|
||||
super().configure(width=self.apply_widget_scaling(self.desired_width),
|
||||
height=self.apply_widget_scaling(self.desired_height))
|
||||
|
||||
# save latest geometry function and kwargs
|
||||
class GeometryCallDict(TypedDict):
|
||||
@ -167,8 +167,8 @@ class CTkBaseClass(tkinter.Frame):
|
||||
self.widget_scaling = new_widget_scaling
|
||||
self.spacing_scaling = new_spacing_scaling
|
||||
|
||||
super().configure(width=self.round_size(self.apply_widget_scaling(self.desired_width)),
|
||||
height=self.round_size(self.apply_widget_scaling(self.desired_height)))
|
||||
super().configure(width=self.apply_widget_scaling(self.desired_width),
|
||||
height=self.apply_widget_scaling(self.desired_height))
|
||||
|
||||
if self.last_geometry_manager_call is not None:
|
||||
self.last_geometry_manager_call["function"](**self.apply_argument_scaling(self.last_geometry_manager_call["kwargs"]))
|
||||
@ -207,13 +207,6 @@ class CTkBaseClass(tkinter.Frame):
|
||||
else:
|
||||
return font
|
||||
|
||||
@staticmethod
|
||||
def round_size(size: Union[int, float, str]):
|
||||
if isinstance(size, (int, float)):
|
||||
return math.floor(size / 2) * 2
|
||||
else:
|
||||
return size
|
||||
|
||||
def draw(self, no_color_updates=False):
|
||||
""" abstract of draw method to be overridden """
|
||||
pass
|
||||
|
@ -5,7 +5,7 @@ import os
|
||||
import platform
|
||||
import ctypes
|
||||
import re
|
||||
from typing import Union
|
||||
from typing import Union, Tuple
|
||||
|
||||
from ..appearance_mode_tracker import AppearanceModeTracker
|
||||
from ..theme_manager import CTkThemeManager
|
||||
@ -33,8 +33,11 @@ class CTk(tkinter.Tk):
|
||||
|
||||
self.current_width = 600 # initial window size, always without scaling
|
||||
self.current_height = 500
|
||||
self.minsize: Union[tuple, None] = None
|
||||
self.maxsize: Union[tuple, None] = None
|
||||
self.min_width: Union[int, None] = None
|
||||
self.min_height: Union[int, None] = None
|
||||
self.max_width: Union[int, None] = None
|
||||
self.max_height: Union[int, None] = None
|
||||
self.last_resizable_args: Union[Tuple[list, dict], None] = None # (args, kwargs)
|
||||
|
||||
self.fg_color = CTkThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
|
||||
|
||||
@ -70,9 +73,25 @@ class CTk(tkinter.Tk):
|
||||
def set_scaling(self, new_widget_scaling, new_spacing_scaling, new_window_scaling):
|
||||
self.window_scaling = new_window_scaling
|
||||
|
||||
# reset min, max and resizable constraints for applying scaling
|
||||
if self.last_resizable_args is not None:
|
||||
super().resizable(True, True)
|
||||
if self.min_width is not None or self.min_height is not None:
|
||||
super().minsize(0, 0)
|
||||
if self.max_width is not None or self.max_height is not None:
|
||||
super().maxsize(1_000_000, 1_000_000)
|
||||
|
||||
# set new window size by applying scaling to the current window size
|
||||
self.geometry(f"{self.current_width}x{self.current_height}")
|
||||
|
||||
# set scaled min, max sizes and reapply resizable
|
||||
if self.last_resizable_args is not None:
|
||||
super().resizable(self.last_resizable_args[0], self.last_resizable_args[1]) # args, kwargs
|
||||
if self.min_width is not None or self.min_height is not None:
|
||||
super().minsize(self.apply_window_scaling(self.min_width), self.apply_window_scaling(self.min_height))
|
||||
if self.max_width is not None or self.max_height is not None:
|
||||
super().maxsize(self.apply_window_scaling(self.max_width), self.apply_window_scaling(self.max_height))
|
||||
|
||||
def destroy(self):
|
||||
AppearanceModeTracker.remove(self.set_appearance_mode)
|
||||
self.disable_macos_dark_title_bar()
|
||||
@ -92,6 +111,7 @@ class CTk(tkinter.Tk):
|
||||
|
||||
def resizable(self, *args, **kwargs):
|
||||
super().resizable(*args, **kwargs)
|
||||
self.last_resizable_args = (args, kwargs)
|
||||
|
||||
if sys.platform.startswith("win"):
|
||||
if self.appearance_mode == 1:
|
||||
@ -99,6 +119,16 @@ class CTk(tkinter.Tk):
|
||||
else:
|
||||
self.windows_set_titlebar_color("light")
|
||||
|
||||
def minsize(self, width=None, height=None):
|
||||
self.min_width = width
|
||||
self.min_height = height
|
||||
super().minsize(self.apply_window_scaling(self.min_width), self.apply_window_scaling(self.min_height))
|
||||
|
||||
def maxsize(self, width=None, height=None):
|
||||
self.max_width = width
|
||||
self.max_height = height
|
||||
super().maxsize(self.apply_window_scaling(self.max_width), self.apply_window_scaling(self.max_height))
|
||||
|
||||
def geometry(self, geometry_string):
|
||||
super().geometry(self.apply_geometry_scaling(geometry_string))
|
||||
|
||||
@ -122,7 +152,7 @@ class CTk(tkinter.Tk):
|
||||
|
||||
def apply_window_scaling(self, value):
|
||||
if isinstance(value, (int, float)):
|
||||
return value * self.window_scaling
|
||||
return int(value * self.window_scaling)
|
||||
else:
|
||||
return value
|
||||
|
||||
|
@ -25,9 +25,6 @@ class App(customtkinter.CTk):
|
||||
self.maxsize(App.WIDTH, App.HEIGHT)
|
||||
|
||||
self.protocol("WM_DELETE_WINDOW", self.on_closing)
|
||||
self.bind("<Command-q>", self.on_closing)
|
||||
self.bind("<Command-w>", self.on_closing)
|
||||
self.createcommand('tk::mac::Quit', self.on_closing)
|
||||
|
||||
# load image with PIL and convert to PhotoImage
|
||||
image = Image.open(PATH + "/test_images/bg_gradient.jpg").resize((self.WIDTH, self.HEIGHT))
|
||||
|
@ -61,4 +61,4 @@ button_5 = customtkinter.CTkButton(master=root_tk, image=add_user_image, text="A
|
||||
command=button_function)
|
||||
button_5.grid(row=0, column=1, padx=20, pady=20)
|
||||
|
||||
root_tk.mainloop()
|
||||
root_tk.mainloop()
|
||||
|
@ -1,18 +0,0 @@
|
||||
import tkinter
|
||||
import customtkinter
|
||||
|
||||
root_tk = customtkinter.CTk()
|
||||
root_tk.geometry("400x240")
|
||||
|
||||
def button_function():
|
||||
root_tk.iconify()
|
||||
root_tk.after(1000, root_tk.deiconify)
|
||||
root_tk.after(2000, root_tk.destroy)
|
||||
|
||||
frame = tkinter.Frame()
|
||||
frame.pack(padx=10, pady=10, expand=True, fill="both")
|
||||
|
||||
button = customtkinter.CTkButton(frame, command=button_function)
|
||||
button.pack(pady=20, padx=20)
|
||||
|
||||
root_tk.mainloop()
|
22
test/visual_tests/test_iconify_destroy.py
Normal file
22
test/visual_tests/test_iconify_destroy.py
Normal file
@ -0,0 +1,22 @@
|
||||
import tkinter
|
||||
import customtkinter
|
||||
|
||||
root_tk = customtkinter.CTk()
|
||||
root_tk.geometry("400x240")
|
||||
|
||||
|
||||
def button_function():
|
||||
|
||||
top = customtkinter.CTkToplevel(root_tk)
|
||||
|
||||
root_tk.after(1000, top.iconify) # hide toplevel
|
||||
root_tk.after(1500, top.deiconify) # show toplevel
|
||||
root_tk.after(2500, root_tk.iconify) # hide root_tk
|
||||
root_tk.after(3000, root_tk.deiconify) # show root_tk
|
||||
root_tk.after(4000, root_tk.destroy) # destroy everything
|
||||
|
||||
|
||||
button = customtkinter.CTkButton(root_tk, command=button_function)
|
||||
button.pack(pady=20, padx=20)
|
||||
|
||||
root_tk.mainloop()
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 885 KiB After Width: | Height: | Size: 885 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@ -10,6 +10,9 @@ root_tk = customtkinter.CTk() # create CTk window like you do with the Tk windo
|
||||
root_tk.geometry("400x480")
|
||||
root_tk.title("CustomTkinter Test")
|
||||
|
||||
root_tk.minsize(480, 480)
|
||||
root_tk.maxsize(520, 520)
|
||||
|
||||
print(customtkinter.ScalingTracker.get_window_scaling(root_tk))
|
||||
|
||||
def button_function():
|
||||
@ -18,6 +21,7 @@ def button_function():
|
||||
|
||||
def slider_function(value):
|
||||
customtkinter.set_user_scaling(value * 2)
|
||||
customtkinter.ScalingTracker.set_window_scaling(value * 2)
|
||||
progressbar_1.set(value)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user