implemented new ColorPicker Widget

This commit is contained in:
Falko Victor Habel 2024-03-28 15:22:48 +01:00
parent 5d1d6638bc
commit 0f44b34701
3 changed files with 63 additions and 55 deletions

View File

@ -1,7 +1,4 @@
# CTk Color Picker for Ctk # this is a modified version of the CTkColorPicker from GitHub
# Original Author: Akash Bora (Akascape)
# Contributers: Victor Vimbert-Guerlais (helloHackYnow)
import customtkinter as Ctk import customtkinter as Ctk
from PIL import Image, ImageTk from PIL import Image, ImageTk
@ -14,23 +11,20 @@ class AskColor(Ctk.CTkToplevel):
def __init__(self, def __init__(self,
master, master,
width: int = 300, font = None,
width: int = 250,
title: str = "Choose Color", title: str = "Choose Color",
initial_color: str = None, initial_color: str = None,
bg_color: str = None,
fg_color: str = None,
button_color: str = None,
button_hover_color: str = None,
text: str = "apply", text: str = "apply",
corner_radius: int = 24, corner_radius: int = 16,
slider_border: int = 1, slider_border: int = 1,
**button_kwargs): **button_kwargs):
super().__init__(master, **button_kwargs) super().__init__(master, **button_kwargs)
self.selected_color = None
self.title(title) self.title(title)
WIDTH = width if width>=200 else 200 WIDTH = width if width >= 250 else 250
HEIGHT = WIDTH + 150 HEIGHT = WIDTH + 110
self.font = font if font is not None else Ctk.CTkFont(family="kDefaultFont", size=16)
self.image_dimension = self._apply_window_scaling(WIDTH - 100) self.image_dimension = self._apply_window_scaling(WIDTH - 100)
self.target_dimension = self._apply_window_scaling(20) self.target_dimension = self._apply_window_scaling(20)
self.initial_color = initial_color self.initial_color = initial_color
@ -39,30 +33,23 @@ class AskColor(Ctk.CTkToplevel):
self.resizable(width=False, height=False) self.resizable(width=False, height=False)
self.transient(self.master) self.transient(self.master)
self.lift() self.lift()
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.after(10) self.after(10)
self.protocol("WM_DELETE_WINDOW", self._on_closing) self.protocol("WM_DELETE_WINDOW", self._on_closing)
self.default_hex_color = "#ffffff" self.default_hex_color = "#ffffff"
self.default_rgb = [255, 255, 255] self.default_rgb = [255, 255, 255]
self.rgb_color = self.default_rgb[:] self.rgb_color = self.default_rgb[:]
self.bg_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkFrame"]["fg_color"]) if bg_color is None else bg_color
self.fg_color = self.fg_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkFrame"]["top_fg_color"]) if fg_color is None else fg_color
self.button_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkButton"]["fg_color"]) if button_color is None else button_color
self.button_hover_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkButton"]["hover_color"]) if button_hover_color is None else button_hover_color
self.button_text = text self.button_text = text
self.corner_radius = corner_radius self.corner_radius = corner_radius
self.slider_border = 10 if slider_border>=10 else slider_border self.slider_border = 10 if slider_border >= 10 else slider_border
self.config(bg=self.bg_color) self.frame = Ctk.CTkFrame(master=self)
self.frame.grid(sticky="nswe", padx=5, pady=5)
self.frame = Ctk.CTkFrame(master=self, fg_color=self.fg_color, bg_color=self.bg_color) self.fg_color = self.fg_color = self._apply_appearance_mode(Ctk.ThemeManager.theme["CTkFrame"]["fg_color"])
self.frame.grid(padx=20, pady=20, sticky="nswe")
self.canvas = Ctk.CTkCanvas(self.frame, height=self.image_dimension, width=self.image_dimension, highlightthickness=0, bg=self.fg_color) self.canvas = Ctk.CTkCanvas(self.frame, height=self.image_dimension, width=self.image_dimension, highlightthickness=0, bg=self.fg_color)
self.canvas.pack(pady=20) self.canvas.grid(row=0, column=0, columnspan=2, pady=20)
self.canvas.bind("<B1-Motion>", self.on_mouse_drag) self.canvas.bind("<B1-Motion>", self.on_mouse_drag)
self.img1 = Image.open(os.path.join(PATH, 'color_wheel.png')).resize((self.image_dimension, self.image_dimension), Image.Resampling.LANCZOS) self.img1 = Image.open(os.path.join(PATH, 'color_wheel.png')).resize((self.image_dimension, self.image_dimension), Image.Resampling.LANCZOS)
@ -81,35 +68,58 @@ class AskColor(Ctk.CTkToplevel):
button_length=15, progress_color=self.default_hex_color, from_=0, to=255, button_length=15, progress_color=self.default_hex_color, from_=0, to=255,
variable=self.brightness_slider_value, number_of_steps=256, variable=self.brightness_slider_value, number_of_steps=256,
button_corner_radius=self.corner_radius, corner_radius=self.corner_radius, button_corner_radius=self.corner_radius, corner_radius=self.corner_radius,
button_color=self.button_color, button_hover_color=self.button_hover_color,
command=lambda x:self.update_colors()) command=lambda x:self.update_colors())
self.slider.pack(fill="both", pady=(0,15), padx=20-self.slider_border)
self.label = Ctk.CTkLabel(master=self.frame, text_color="#000000", height=50, fg_color=self.default_hex_color,
corner_radius=self.corner_radius, text=self.default_hex_color)
self.label.pack(fill="both", padx=10)
self.button = Ctk.CTkButton(master=self.frame, text=self.button_text, height=50, corner_radius=self.corner_radius, fg_color=self.button_color, self.slider.grid(row=1, column=0, columnspan=2, pady=(0, 15), padx=20-self.slider_border)
hover_color=self.button_hover_color, command=self._ok_event, **button_kwargs)
self.button.pack(fill="both", padx=10, pady=20) self.label = Ctk.CTkLabel(master=self.frame, text_color="#000000", height=50, width=75, fg_color=self.default_hex_color,
corner_radius=self.corner_radius, text="")
self.color_entry = Ctk.CTkEntry(master=self.frame, height=50, corner_radius=self.corner_radius, font=self.font, width=100)
self.color_entry.configure(placeholder_text=self.default_hex_color) # Insert the new text
self.button = Ctk.CTkButton(master=self.frame, text=self.button_text, height=50, corner_radius=self.corner_radius,width = 200,
command=self._ok_event, **button_kwargs)
self.label.grid(row=2, column=0, padx=(5, 20), pady=10, sticky="e")
self.color_entry.grid(row=2, column=1, padx=(5, 5), pady=10, sticky="w")
self.button.grid(row=3, column=0, columnspan=3, padx=5, pady=10)
self.after(150, lambda: self.label.focus()) self.after(150, lambda: self.label.focus())
self.grab_set() self.grab_set()
def get(self): def get(self):
self._color = self.label._fg_color # Use the stored selected_color instead of accessing the widget
self.wait_window(self) return self.selected_color
return self._color
def _ok_event(self, event=None): def _ok_event(self, event=None):
self._color = self.label._fg_color input_string = self.color_entry.get()
self.selected_color = self.check_rgb_hex_color(input_string) # Store the selected color
self.grab_release() self.grab_release()
self.destroy() self.destroy()
del self.img1 del self.img1
del self.img2 del self.img2
del self.wheel del self.wheel
del self.target del self.target
def check_rgb_hex_color(self, input_string):
if not input_string:
return self.default_hex_color
if not input_string.startswith("#"):
input_string = "#" + input_string
hex_color = input_string.lstrip("#")
if len(hex_color) != 6:
return None
try:
int(hex_color, 16)
return input_string
except ValueError:
return None
def _on_closing(self): def _on_closing(self):
self._color = None self._color = None
@ -166,15 +176,9 @@ class AskColor(Ctk.CTkToplevel):
self.slider.configure(progress_color=self.default_hex_color) self.slider.configure(progress_color=self.default_hex_color)
self.label.configure(fg_color=self.default_hex_color) self.label.configure(fg_color=self.default_hex_color)
self.label.configure(text=str(self.default_hex_color)) self.color_entry.delete(0, Ctk.END) # Delete any existing text in the color_entry widget
self.color_entry.configure(placeholder_text=self.default_hex_color) # Insert the new text
if self.brightness_slider_value.get() < 70:
self.label.configure(text_color="white")
else:
self.label.configure(text_color="black")
if str(self.label._fg_color)=="black":
self.label.configure(text_color="white")
def projection_on_circle(self, point_x, point_y, circle_x, circle_y, radius): def projection_on_circle(self, point_x, point_y, circle_x, circle_y, radius):
angle = math.atan2(point_y - circle_y, point_x - circle_x) angle = math.atan2(point_y - circle_y, point_x - circle_x)
@ -261,5 +265,7 @@ class AskColor(Ctk.CTkToplevel):
self.canvas.create_image(center, center, image=self.target) self.canvas.create_image(center, center, image=self.target)
if __name__ == "__main__": if __name__ == "__main__":
app = AskColor() app = AskColor(master=None, font=None)
app.mainloop() app.wait_window(app) # This waits until the window is closed
color = app.get() # Access the color stored before the window was destroyed
print("Selected color:", color)

View File

@ -4,7 +4,7 @@ from PIL import Image
import scripts.get_sys_info as system_code import scripts.get_sys_info as system_code
from scripts.ClosePopup import ClosePopup from scripts.ClosePopup import ClosePopup
from scripts.Settings import Settings from scripts.settings import Settings
from scripts.Converter import Converter from scripts.Converter import Converter
from scripts.Labeling import Labeling from scripts.Labeling import Labeling

View File

@ -69,8 +69,10 @@ class Settings(Ctk.CTkFrame):
self.thickness_slider_value.configure(text=value) self.thickness_slider_value.configure(text=value)
def ask_color(self): def ask_color(self):
self.pick_color = AskColor(master=self.master, initial_color=system_code.color) self.pick_color = AskColor(master=self.master, font=self.my_font)
self.wait_window(self.pick_color)
self.color = self.pick_color.get() # get the color string self.color = self.pick_color.get() # get the color string
if self.color is not None: if self.color is not None:
self.color_btn.configure(fg_color=self.color) self.color_btn.configure(fg_color=self.color)
# set the wanted image format # set the wanted image format