mirror of
https://github.com/TomSchimansky/CustomTkinter.git
synced 2023-08-10 21:13:13 +03:00
small fixes
This commit is contained in:
parent
afc8ce8c3d
commit
ecd4881ffb
@ -1,4 +1,4 @@
|
||||
__version__ = "2.3"
|
||||
__version__ = "2.4"
|
||||
|
||||
from .customtkinter_button import CTkButton
|
||||
from .customtkinter_slider import CTkSlider
|
||||
|
@ -51,7 +51,7 @@
|
||||
"progressbar_corner_radius": 100,
|
||||
"slider_border_width": 5,
|
||||
"slider_corner_radius": 8,
|
||||
"slider_button_length": 0,
|
||||
"slider_button_length": 10,
|
||||
"slider_button_corner_radius": 8
|
||||
}
|
||||
}
|
@ -98,7 +98,7 @@ class CTkDrawEngine:
|
||||
|
||||
# create inner button parts
|
||||
if not self._canvas.find_withtag("inner_parts"):
|
||||
self._canvas.create_polygon((0, 0, 0, 0), tags=("inner_line_1", "inner_parts"))
|
||||
self._canvas.create_polygon((0, 0, 0, 0), tags=("inner_line_1", "inner_parts"), joinstyle=tkinter.ROUND)
|
||||
requires_recoloring = True
|
||||
|
||||
if corner_radius <= border_width:
|
||||
@ -107,19 +107,18 @@ class CTkDrawEngine:
|
||||
bottom_right_shift = 0
|
||||
|
||||
self._canvas.coords("inner_line_1",
|
||||
(border_width + inner_corner_radius,
|
||||
border_width + inner_corner_radius,
|
||||
border_width + inner_corner_radius,
|
||||
width - (border_width + inner_corner_radius) + bottom_right_shift,
|
||||
border_width + inner_corner_radius,
|
||||
width - (border_width + inner_corner_radius) + bottom_right_shift,
|
||||
height - (border_width + inner_corner_radius) + bottom_right_shift,
|
||||
border_width + inner_corner_radius,
|
||||
height - (border_width + inner_corner_radius) + bottom_right_shift))
|
||||
height - (border_width + inner_corner_radius) + bottom_right_shift)
|
||||
self._canvas.itemconfig("inner_line_1",
|
||||
joinstyle=tkinter.ROUND,
|
||||
width=inner_corner_radius * 2)
|
||||
|
||||
if requires_recoloring:
|
||||
if requires_recoloring: # new parts were added -> manage z-order
|
||||
self._canvas.tag_lower("inner_parts")
|
||||
self._canvas.tag_lower("border_parts")
|
||||
|
||||
@ -238,7 +237,7 @@ class CTkDrawEngine:
|
||||
width - border_width,
|
||||
height - inner_corner_radius - border_width))
|
||||
|
||||
if requires_recoloring:
|
||||
if requires_recoloring: # new parts were added -> manage z-order
|
||||
self._canvas.tag_lower("inner_parts")
|
||||
self._canvas.tag_lower("border_parts")
|
||||
|
||||
@ -350,7 +349,7 @@ class CTkDrawEngine:
|
||||
requires_recoloring = self._draw_rounded_rect_with_border_polygon_shapes(width, height, corner_radius, border_width, inner_corner_radius)
|
||||
|
||||
if corner_radius <= border_width:
|
||||
bottom_right_shift = -1 # weird canvas rendering inaccuracy that has to be corrected in some cases
|
||||
bottom_right_shift = 0 # weird canvas rendering inaccuracy that has to be corrected in some cases
|
||||
else:
|
||||
bottom_right_shift = 0
|
||||
|
||||
@ -503,14 +502,6 @@ class CTkDrawEngine:
|
||||
else:
|
||||
inner_corner_radius = 0
|
||||
|
||||
# scale slider_value to a smaller range to be the progress_value of the underlaying progressbar
|
||||
if orientation == "w" or orientation == "e":
|
||||
x = (button_length / width) / 2
|
||||
else:
|
||||
x = (button_length / height) / 2
|
||||
print(x)
|
||||
new_slider_value = slider_value * (1 - 2 * x) + x
|
||||
|
||||
if self._rendering_method == "polygon_shapes" or self._rendering_method == "circle_shapes":
|
||||
return self._draw_rounded_slider_with_border_and_button_polygon_shapes(width, height, corner_radius, border_width, inner_corner_radius,
|
||||
button_length, button_corner_radius, slider_value, orientation)
|
||||
@ -521,13 +512,14 @@ class CTkDrawEngine:
|
||||
def _draw_rounded_slider_with_border_and_button_polygon_shapes(self, width: int, height: int, corner_radius: int, border_width: int, inner_corner_radius: int,
|
||||
button_length: int, button_corner_radius: int, slider_value: float, orientation: str) -> bool:
|
||||
|
||||
# draw normal progressbar
|
||||
requires_recoloring = self._draw_rounded_progress_bar_with_border_polygon_shapes(width, height, corner_radius, border_width, inner_corner_radius,
|
||||
slider_value, orientation)
|
||||
|
||||
# create button parts
|
||||
# create slider button part
|
||||
if not self._canvas.find_withtag("slider_parts"):
|
||||
self._canvas.create_polygon((0, 0, 0, 0), tags=("slider_line_1", "slider_parts"), joinstyle=tkinter.ROUND)
|
||||
self._canvas.tag_raise("slider_parts")
|
||||
self._canvas.tag_raise("slider_parts") # manage z-order
|
||||
requires_recoloring = True
|
||||
|
||||
if corner_radius <= border_width:
|
||||
@ -550,9 +542,11 @@ class CTkDrawEngine:
|
||||
def _draw_rounded_slider_with_border_and_button_font_shapes(self, width: int, height: int, corner_radius: int, border_width: int, inner_corner_radius: int,
|
||||
button_length: int, button_corner_radius: int, slider_value: float, orientation: str) -> bool:
|
||||
|
||||
# draw normal progressbar
|
||||
requires_recoloring = self._draw_rounded_progress_bar_with_border_font_shapes(width, height, corner_radius, border_width, inner_corner_radius,
|
||||
slider_value, orientation)
|
||||
|
||||
# create 4 circles (if not needed, then less)
|
||||
if not self._canvas.find_withtag("slider_oval_1_a"):
|
||||
self._canvas.create_aa_circle(0, 0, 0, tags=("slider_oval_1_a", "slider_corner_part", "slider_parts"), anchor=tkinter.CENTER)
|
||||
self._canvas.create_aa_circle(0, 0, 0, tags=("slider_oval_1_b", "slider_corner_part", "slider_parts"), anchor=tkinter.CENTER, angle=180)
|
||||
@ -579,6 +573,7 @@ class CTkDrawEngine:
|
||||
elif self._canvas.find_withtag("border_oval_3_a") and not (button_length > 0 and height > 2 * button_corner_radius):
|
||||
self._canvas.delete("slider_oval_3_a", "slider_oval_3_b")
|
||||
|
||||
# create the 2 rectangles (if needed)
|
||||
if not self._canvas.find_withtag("slider_rectangle_1") and button_length > 0:
|
||||
self._canvas.create_rectangle(0, 0, 0, 0, tags=("slider_rectangle_1", "slider_rectangle_part", "slider_parts"), width=0)
|
||||
requires_recoloring = True
|
||||
@ -591,6 +586,7 @@ class CTkDrawEngine:
|
||||
elif self._canvas.find_withtag("slider_rectangle_2") and not height > 2 * button_corner_radius:
|
||||
self._canvas.delete("slider_rectangle_2")
|
||||
|
||||
# set positions of circles and rectangles
|
||||
slider_x_position = corner_radius + (button_length / 2) + (width - 2 * corner_radius - button_length) * slider_value
|
||||
self._canvas.coords("slider_oval_1_a", slider_x_position - (button_length / 2), button_corner_radius, button_corner_radius)
|
||||
self._canvas.coords("slider_oval_1_b", slider_x_position - (button_length / 2), button_corner_radius, button_corner_radius)
|
||||
@ -608,7 +604,7 @@ class CTkDrawEngine:
|
||||
slider_x_position - (button_length / 2) - button_corner_radius, button_corner_radius,
|
||||
slider_x_position + (button_length / 2) + button_corner_radius, height - button_corner_radius)
|
||||
|
||||
if requires_recoloring:
|
||||
if requires_recoloring: # new parts were added -> manage z-order
|
||||
self._canvas.tag_raise("slider_parts")
|
||||
|
||||
return requires_recoloring
|
||||
return requires_recoloring
|
||||
|
@ -1,5 +1,4 @@
|
||||
import tkinter
|
||||
import sys
|
||||
|
||||
from .customtkinter_tk import CTk
|
||||
from .customtkinter_frame import CTkFrame
|
||||
@ -19,8 +18,8 @@ class CTkEntry(tkinter.Frame):
|
||||
placeholder_text_color="default_theme",
|
||||
text_font="default_theme",
|
||||
placeholder_text=None,
|
||||
corner_radius=8,
|
||||
border_width=0,
|
||||
corner_radius="default_theme",
|
||||
border_width="default_theme",
|
||||
border_color="default_theme",
|
||||
width=120,
|
||||
height=30,
|
||||
|
@ -69,11 +69,14 @@ class CTkLabel(tkinter.Frame):
|
||||
self.text = text
|
||||
self.text_font = (CTkThemeManager.theme["text"]["font"], CTkThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
|
||||
|
||||
self.grid_rowconfigure(0, weight=1)
|
||||
self.grid_columnconfigure(0, weight=1)
|
||||
|
||||
self.canvas = CTkCanvas(master=self,
|
||||
highlightthickness=0,
|
||||
width=self.width,
|
||||
height=self.height)
|
||||
self.canvas.place(relx=0, rely=0, anchor=tkinter.NW)
|
||||
self.canvas.grid(row=0, column=0, sticky="nswe")
|
||||
|
||||
self.text_label = tkinter.Label(master=self,
|
||||
highlightthickness=0,
|
||||
@ -81,7 +84,7 @@ class CTkLabel(tkinter.Frame):
|
||||
text=self.text,
|
||||
font=self.text_font,
|
||||
**kwargs)
|
||||
self.text_label.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
|
||||
self.text_label.grid(row=0, column=0, padx=self.corner_radius)
|
||||
|
||||
self.draw_engine = CTkDrawEngine(self.canvas, CTkSettings.preferred_drawing_method)
|
||||
|
||||
@ -134,8 +137,6 @@ class CTkLabel(tkinter.Frame):
|
||||
if "fg_color" in kwargs:
|
||||
self.fg_color = kwargs["fg_color"]
|
||||
require_redraw = True
|
||||
if self.fg_color is None:
|
||||
self.fg_color = self.bg_color
|
||||
del kwargs["fg_color"]
|
||||
|
||||
if "bg_color" in kwargs:
|
||||
|
@ -156,20 +156,12 @@ class CTkSlider(tkinter.Frame):
|
||||
|
||||
self.draw()
|
||||
|
||||
def draw(self, no_color_updates=False):
|
||||
|
||||
# # 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()
|
||||
# else:
|
||||
# # on Windows and other draw with ovals (corner_radius can be optimised to look better than with polygons)
|
||||
# self.draw_with_ovals_and_rects()
|
||||
def draw(self, color_updates=True):
|
||||
|
||||
requires_recoloring = self.draw_engine.draw_rounded_slider_with_border_and_button(self.width, self.height, self.corner_radius, self.border_width,
|
||||
self.button_length, self.button_corner_radius, self.value, "w")
|
||||
|
||||
if no_color_updates is False or requires_recoloring:
|
||||
if color_updates or requires_recoloring:
|
||||
self.canvas.configure(bg=CTkThemeManager.single_color(self.bg_color, self.appearance_mode))
|
||||
|
||||
if self.border_color is None:
|
||||
@ -192,146 +184,6 @@ class CTkSlider(tkinter.Frame):
|
||||
self.canvas.itemconfig("slider_parts", fill=CTkThemeManager.single_color(self.button_color, self.appearance_mode),
|
||||
outline=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 """
|
||||
|
||||
coordinate_shift = -1
|
||||
width_reduced = -1
|
||||
|
||||
# create border parts
|
||||
if self.border_width > 0:
|
||||
if not self.canvas.find_withtag("border_parts"):
|
||||
self.canvas.create_line((0, 0, 0, 0), tags=("border_line_1", "border_parts"))
|
||||
|
||||
self.canvas.coords("border_line_1",
|
||||
(self.height / 2,
|
||||
self.height / 2,
|
||||
self.width - self.height / 2 + coordinate_shift,
|
||||
self.height / 2))
|
||||
self.canvas.itemconfig("border_line_1",
|
||||
capstyle=tkinter.ROUND,
|
||||
width=self.height + width_reduced)
|
||||
|
||||
# create inner button parts
|
||||
if not self.canvas.find_withtag("inner_parts"):
|
||||
self.canvas.create_line((0, 0, 0, 0), tags=("inner_line_1", "inner_parts"))
|
||||
|
||||
if self.progress_color != self.fg_color:
|
||||
if not self.canvas.find_withtag("progress_parts"):
|
||||
self.canvas.create_line((0, 0, 0, 0), tags=("inner_line_progress", "progress_parts"))
|
||||
self.canvas.tag_raise("button_parts")
|
||||
else:
|
||||
self.canvas.delete("progress_parts")
|
||||
|
||||
self.canvas.coords("inner_line_1",
|
||||
(((self.width + coordinate_shift - self.height) * self.value + self.height / 2),
|
||||
self.height / 2,
|
||||
self.width - self.height / 2 + coordinate_shift,
|
||||
self.height / 2))
|
||||
|
||||
if self.progress_color != self.fg_color:
|
||||
self.canvas.coords("inner_line_progress",
|
||||
(self.height / 2,
|
||||
self.height / 2,
|
||||
((self.width + coordinate_shift - self.height) * self.value + self.height / 2),
|
||||
self.height / 2))
|
||||
|
||||
self.canvas.itemconfig("inner_parts",
|
||||
capstyle=tkinter.ROUND,
|
||||
width=self.height - self.border_width * 2 + width_reduced)
|
||||
self.canvas.itemconfig("progress_parts",
|
||||
capstyle=tkinter.ROUND,
|
||||
width=self.height - self.border_width * 2 + width_reduced)
|
||||
|
||||
# button parts
|
||||
if not self.canvas.find_withtag("button_parts"):
|
||||
self.canvas.create_line((0, 0, 0, 0), tags=("button_line_1", "button_parts"))
|
||||
|
||||
self.canvas.coords("button_line_1",
|
||||
(self.height / 2 + (self.width + coordinate_shift - self.height) * self.value,
|
||||
self.height / 2,
|
||||
self.height / 2 + (self.width + coordinate_shift - self.height) * self.value,
|
||||
self.height / 2))
|
||||
self.canvas.itemconfig("button_line_1",
|
||||
capstyle=tkinter.ROUND,
|
||||
width=self.height + width_reduced)
|
||||
|
||||
def draw_with_ovals_and_rects(self):
|
||||
""" draw the progress bar parts with ovals and rectangles """
|
||||
|
||||
# ovals and rects are always rendered too large and need to be made smaller by -1
|
||||
oval_bottom_right_shift = -1
|
||||
rect_bottom_right_shift = 0
|
||||
|
||||
# frame_border
|
||||
if self.border_width > 0:
|
||||
if not self.canvas.find_withtag("border_parts"):
|
||||
self.canvas.create_oval((0, 0, 0, 0), tags=("border_oval_1", "border_parts"), width=0)
|
||||
self.canvas.create_rectangle((0, 0, 0, 0), tags=("border_rect_1", "border_parts"), width=0)
|
||||
self.canvas.create_oval((0, 0, 0, 0), tags=("border_oval_2", "border_parts"), width=0)
|
||||
|
||||
self.canvas.coords("border_oval_1", (0,
|
||||
0,
|
||||
self.height + oval_bottom_right_shift,
|
||||
self.height + oval_bottom_right_shift))
|
||||
self.canvas.coords("border_rect_1", (self.height/2,
|
||||
0,
|
||||
self.width-(self.height/2) + rect_bottom_right_shift,
|
||||
self.height + rect_bottom_right_shift))
|
||||
self.canvas.coords("border_oval_2", (self.width-self.height,
|
||||
0,
|
||||
self.width + oval_bottom_right_shift,
|
||||
self.height + oval_bottom_right_shift))
|
||||
|
||||
# foreground
|
||||
if not self.canvas.find_withtag("inner_parts"):
|
||||
self.canvas.create_rectangle((0, 0, 0, 0), tags=("inner_rect_2", "inner_parts"), width=0)
|
||||
self.canvas.create_oval((0, 0, 0, 0), tags=("inner_oval_2", "inner_parts"), width=0)
|
||||
|
||||
# progress parts
|
||||
if not self.canvas.find_withtag("inner_oval_1"):
|
||||
self.canvas.delete("inner_oval_1", "inner_rect_1")
|
||||
|
||||
if self.progress_color != self.fg_color:
|
||||
self.canvas.create_oval((0, 0, 0, 0), tags=("inner_oval_1", "progress_parts"), width=0)
|
||||
self.canvas.create_rectangle((0, 0, 0, 0), tags=("inner_rect_1", "progress_parts"), width=0)
|
||||
else:
|
||||
self.canvas.create_oval((0, 0, 0, 0), tags=("inner_oval_1", "inner_parts"), width=0)
|
||||
|
||||
if self.progress_color != self.fg_color:
|
||||
self.canvas.coords("inner_rect_1", (self.height / 2,
|
||||
self.border_width,
|
||||
(self.width - self.height) * self.value + (self.height / 2 + rect_bottom_right_shift),
|
||||
self.height - self.border_width + rect_bottom_right_shift))
|
||||
self.canvas.coords("inner_rect_2", ((self.width - self.height) * self.value + (self.height / 2 + rect_bottom_right_shift),
|
||||
self.border_width,
|
||||
self.width - (self.height / 2 + rect_bottom_right_shift),
|
||||
self.height - self.border_width + rect_bottom_right_shift))
|
||||
else:
|
||||
self.canvas.coords("inner_rect_2", (self.height/2,
|
||||
self.border_width,
|
||||
self.width-(self.height/2 + rect_bottom_right_shift),
|
||||
self.height-self.border_width + rect_bottom_right_shift))
|
||||
|
||||
self.canvas.coords("inner_oval_1", (self.border_width,
|
||||
self.border_width,
|
||||
self.height - self.border_width + oval_bottom_right_shift,
|
||||
self.height - self.border_width + oval_bottom_right_shift))
|
||||
self.canvas.coords("inner_oval_2", (self.width-self.height+self.border_width,
|
||||
self.border_width,
|
||||
self.width-self.border_width + oval_bottom_right_shift,
|
||||
self.height-self.border_width + oval_bottom_right_shift))
|
||||
|
||||
# progress parts
|
||||
if not self.canvas.find_withtag("button_parts"):
|
||||
self.canvas.create_oval((0, 0, 0, 0), tags=("button_oval_1", "button_parts"), width=0)
|
||||
|
||||
self.canvas.coords("button_oval_1",
|
||||
((self.width - self.height) * self.value,
|
||||
0,
|
||||
self.height + (self.width - self.height) * self.value + oval_bottom_right_shift,
|
||||
self.height + oval_bottom_right_shift))
|
||||
|
||||
def clicked(self, event=None):
|
||||
self.value = event.x / self.width
|
||||
|
||||
@ -343,7 +195,7 @@ class CTkSlider(tkinter.Frame):
|
||||
self.output_value = self.round_to_step_size(self.from_ + (self.value * (self.to - self.from_)))
|
||||
self.value = (self.output_value - self.from_) / (self.to - self.from_)
|
||||
|
||||
self.draw(no_color_updates=True)
|
||||
self.draw(color_updates=False)
|
||||
|
||||
if self.callback_function is not None:
|
||||
self.callback_function(self.output_value)
|
||||
@ -389,7 +241,7 @@ class CTkSlider(tkinter.Frame):
|
||||
self.output_value = self.round_to_step_size(output_value)
|
||||
self.value = (self.output_value - self.from_) / (self.to - self.from_)
|
||||
|
||||
self.draw(no_color_updates=True)
|
||||
self.draw(color_updates=False)
|
||||
|
||||
if self.callback_function is not None:
|
||||
self.callback_function(self.output_value)
|
||||
|
@ -18,7 +18,7 @@ class CTkToplevel(tkinter.Toplevel):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.appearance_mode = AppearanceModeTracker.get_mode() # 0: "Light" 1: "Dark"
|
||||
|
||||
self.fg_color = CTkThemeManager.WINDOW_BG_COLOR if fg_color == "default_theme" else fg_color
|
||||
self.fg_color = CTkThemeManager.theme["color"]["window_bg_color"] if fg_color == "default_theme" else fg_color
|
||||
|
||||
if "bg" in kwargs:
|
||||
self.fg_color = kwargs["bg"]
|
||||
|
2
setup.py
2
setup.py
@ -19,7 +19,7 @@ def read(filename):
|
||||
|
||||
|
||||
setup(name="customtkinter",
|
||||
version="2.3",
|
||||
version="2.4",
|
||||
author="Tom Schimansky",
|
||||
license="Creative Commons Zero v1.0 Universal",
|
||||
url="https://github.com/TomSchimansky/CustomTkinter",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import customtkinter
|
||||
import tkinter
|
||||
|
||||
customtkinter.CTkSettings.preferred_drawing_method = "font_shapes"
|
||||
customtkinter.CTkSettings.preferred_drawing_method = "polygon_shapes"
|
||||
customtkinter.set_default_color_theme("blue")
|
||||
customtkinter.set_appearance_mode("dark")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user