Jul-06-2022, 01:03 PM
It is unusual for a dialog to stay open, and generally considered bad user interface design. If you have something that should be always available it should be part of the main interface, not a popup.
If you want to make a color picker with sliders, here's a starting point.
If you want to make a color picker with sliders, here's a starting point.
import tkinter as tk from tkinter import ttk import random class Slider(ttk.Frame): def __init__(self, parent, text, max=100, min=0, command=None): super().__init__(parent) top = ttk.Frame(self) bottom = ttk.Frame(self) self.label = ttk.Label(top, text=text, justify=tk.LEFT) self.display_value = tk.StringVar(self, "0") self.display_value.trace("w", lambda a, b, c: self.display_changed(self.display_value.get())) self.display = ttk.Entry(top, width=10, textvariable=self.display_value) self.scale_value = tk.DoubleVar(self, 0.0) self.scale = ttk.Scale(bottom, from_=min, to=max, variable=self.scale_value, command=self.scale_changed) self.min = min self.max = max self.command = command self.label.pack(side=tk.LEFT) self.display.pack(side=tk.RIGHT) self.scale.pack(expand=True, fill=tk.BOTH) top.pack(side=tk.TOP, expand=True, fill=tk.BOTH) bottom.pack(side=tk.TOP, expand=True, fill=tk.BOTH) def scale_changed(self, value): self.display_value.set(int(round(float(value)))) def display_changed(self, value): try: value = int(value) except ValueError: pass else: value = max(self.min, min(self.max, value)) self.display_value.set(value) self.scale_value.set(value) if self.command is not None: self.command(value) @property def value(self): return int(self.scale_value.get()) @value.setter def value(self, new_value): self.display_changed(new_value) class ColorChooser(tk.Toplevel): def __init__(self, command=None): super().__init__() self.title("Colors") self.red = Slider(self, text="Red", max=255, command=self.color_changed) self.green = Slider(self, text="Green", max=255, command=self.color_changed) self.blue = Slider(self, text="Blue", max=255, command=self.color_changed) self._color = "#000000" self.apply = tk.Button(self, text="Apply", fg="white", bg=self._color, command=self.apply_pressed) self.red.pack(expand=True, fill=tk.BOTH, padx=5, pady=5) self.green.pack(expand=True, fill=tk.BOTH, padx=5, pady=5) self.blue.pack(expand=True, fill=tk.BOTH, padx=5, pady=5) self.apply.pack(expand=True, fill=tk.BOTH, padx=5, pady=5) self.command = command def color_changed(self, _): r = self.red.value g = self.green.value b = self.blue.value self._color = f"#{r:02x}{g:02x}{b:02x}" fg = "white" if r + g + b < 300 else "black" self.apply.config(fg=fg, bg=self.color) def apply_pressed(self): if self.command is not None: self.command(self.color) @property def color(self): return self._color @color.setter def color(self, new_value): try: r = int(new_value[1:3], base=16) g = int(new_value[3:5], base=16) b = int(new_value[5:7], base=16) print(r, g, b) except (ValueError, IndexError) as msg: print(msg) else: self.red.value = r self.green.value = g self.blue.value = b class MainPanel(tk.Tk): def __init__(self): super().__init__() self.title("Main Panel") self.style = ttk.Style() themes = self.style.theme_names() self.theme = tk.StringVar(self, themes[0]) self.theme.trace("w", lambda a, b, c: self.style.theme_use(self.theme.get())) theme_slector = ttk.Combobox(self, values=themes, textvariable=self.theme) theme_slector.pack(padx=40, pady=20) chooser = ColorChooser(command=print) chooser.color = "#a0b0c0" MainPanel().mainloop()