enhanced .configure() process for all widgets

This commit is contained in:
Tom Schimansky 2022-07-07 16:02:51 +02:00
parent a2fcb5dee1
commit 767379462e
14 changed files with 57 additions and 214 deletions

View File

@ -1,6 +1,6 @@
import tkinter
import sys
import math
from typing import Union
from .ctk_canvas import CTkCanvas
from ..theme_manager import ThemeManager
@ -29,8 +29,8 @@ class CTkButton(CTkBaseClass):
text="CTkButton",
hover=True,
image=None,
compound=tkinter.LEFT,
state=tkinter.NORMAL,
compound="left",
state="normal",
**kwargs):
# transfer basic functionality (bg_color, size, _appearance_mode, scaling) to CTkBaseClass
@ -42,18 +42,18 @@ class CTkButton(CTkBaseClass):
self.fg_color = ThemeManager.theme["color"]["button"] if fg_color == "default_theme" else fg_color
self.hover_color = ThemeManager.theme["color"]["button_hover"] if hover_color == "default_theme" else hover_color
self.border_color = ThemeManager.theme["color"]["button_border"] if border_color == "default_theme" else border_color
self.text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.text_color_disabled = ThemeManager.theme["color"]["text_button_disabled"] if text_color_disabled == "default_theme" else text_color_disabled
# shape
self.corner_radius = ThemeManager.theme["shape"]["button_corner_radius"] if corner_radius == "default_theme" else corner_radius
self.border_width = ThemeManager.theme["shape"]["button_border_width"] if border_width == "default_theme" else border_width
# text and font and image
# text, font, image
self.image = image
self.image_label = None
self.text = text
self.text_label = None
self.text_color = ThemeManager.theme["color"]["text"] if text_color == "default_theme" else text_color
self.text_color_disabled = ThemeManager.theme["color"]["text_button_disabled"] if text_color_disabled == "default_theme" else text_color_disabled
self.text_font = (ThemeManager.theme["text"]["font"], ThemeManager.theme["text"]["size"]) if text_font == "default_theme" else text_font
# callback and hover functionality
@ -237,12 +237,10 @@ class CTkButton(CTkBaseClass):
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
def configure(self, require_redraw=False, **kwargs):
if "text" in kwargs:
self.text = kwargs.pop("text")
require_redraw = True # new text will be set in .draw()
require_redraw = True # new text will be set to label in .draw()
if "state" in kwargs:
self.state = kwargs.pop("state")
@ -265,14 +263,6 @@ class CTkButton(CTkBaseClass):
self.border_color = kwargs.pop("border_color")
require_redraw = True
if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = new_bg_color
require_redraw = True
if "hover_color" in kwargs:
self.hover_color = kwargs.pop("hover_color")
require_redraw = True
@ -295,10 +285,7 @@ class CTkButton(CTkBaseClass):
if "height" in kwargs:
self.set_dimensions(height=kwargs.pop("height"))
super().configure(*args, **kwargs)
if require_redraw:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)
def set_cursor(self):
if Settings.cursor_manipulation_enabled:

View File

@ -171,9 +171,7 @@ class CTkCheckBox(CTkBaseClass):
self.text_label.configure(bg=ThemeManager.single_color(self.bg_color, self._appearance_mode))
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw()
def configure(self, require_redraw=False, **kwargs):
if "text" in kwargs:
self.text = kwargs.pop("text")
self.text_label.configure(text=self.text)
@ -187,13 +185,6 @@ class CTkCheckBox(CTkBaseClass):
self.fg_color = kwargs.pop("fg_color")
require_redraw = True
if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = new_bg_color
if "hover_color" in kwargs:
self.hover_color = kwargs.pop("hover_color")
require_redraw = True
@ -224,10 +215,7 @@ class CTkCheckBox(CTkBaseClass):
self.check_state = True if self.variable.get() == self.onvalue else False
require_redraw = True
super().configure(*args, **kwargs)
if require_redraw:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)
def set_cursor(self):
if Settings.cursor_manipulation_enabled:

View File

@ -183,9 +183,7 @@ class CTkComboBox(CTkBaseClass):
self.dropdown_menu.open(self.winfo_rootx(),
self.winfo_rooty() + self.apply_widget_scaling(self._current_height + 0))
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
def configure(self, require_redraw=False, **kwargs):
if "state" in kwargs:
self.state = kwargs.pop("state")
self.entry.configure(state=self.state)
@ -195,14 +193,6 @@ class CTkComboBox(CTkBaseClass):
self.fg_color = kwargs.pop("fg_color")
require_redraw = True
if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = new_bg_color
require_redraw = True
if "button_color" in kwargs:
self.button_color = kwargs.pop("button_color")
require_redraw = True
@ -244,10 +234,7 @@ class CTkComboBox(CTkBaseClass):
if "dropdown_text_font" in kwargs:
self.dropdown_menu.configure(text_font=kwargs.pop("dropdown_text_font"))
super().configure(*args, **kwargs)
if require_redraw:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)
def on_enter(self, event=0):
if self.hover is True and self.state == tkinter.NORMAL and len(self.values) > 0:

View File

@ -24,8 +24,7 @@ class CTkEntry(CTkBaseClass):
# transfer basic functionality (bg_color, size, _appearance_mode, scaling) to CTkBaseClass
if "master" in kwargs:
super().__init__(*args, bg_color=bg_color, width=width, height=height, master=kwargs["master"])
del kwargs["master"]
super().__init__(*args, bg_color=bg_color, width=width, height=height, master=kwargs.pop("master"))
else:
super().__init__(*args, bg_color=bg_color, width=width, height=height)
@ -132,21 +131,11 @@ class CTkEntry(CTkBaseClass):
def bind(self, *args, **kwargs):
self.entry.bind(*args, **kwargs)
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
def configure(self, require_redraw=False, **kwargs):
if "state" in kwargs:
self.state = kwargs.pop("state")
self.entry.configure(state=self.state)
if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = new_bg_color
require_redraw = True
if "fg_color" in kwargs:
self.fg_color = kwargs.pop("fg_color")
require_redraw = True
@ -192,10 +181,12 @@ class CTkEntry(CTkBaseClass):
else:
self.entry.configure(show=kwargs.pop("show"))
self.entry.configure(*args, **kwargs)
if "bg_color" in kwargs:
super().configure(bg_color=kwargs.pop("bg_color"), require_redraw=require_redraw)
else:
super().configure(require_redraw=require_redraw)
if require_redraw is True:
self.draw()
self.entry.configure(**kwargs) # pass remaining kwargs to entry
def set_placeholder(self):
self.pre_placeholder_arguments = {"show": self.entry.cget("show")}

View File

@ -101,9 +101,7 @@ class CTkFrame(CTkBaseClass):
self.canvas.tag_lower("inner_parts")
self.canvas.tag_lower("border_parts")
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
def configure(self, require_redraw=False, **kwargs):
if "fg_color" in kwargs:
self.fg_color = kwargs.pop("fg_color")
require_redraw = True
@ -113,14 +111,6 @@ class CTkFrame(CTkBaseClass):
if isinstance(child, CTkBaseClass):
child.configure(bg_color=self.fg_color)
if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = new_bg_color
require_redraw = True
if "border_color" in kwargs:
self.border_color = kwargs.pop("border_color")
require_redraw = True
@ -139,7 +129,4 @@ class CTkFrame(CTkBaseClass):
if "height" in kwargs:
self.set_dimensions(height=kwargs.pop("height"))
super().configure(*args, **kwargs)
if require_redraw:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)

View File

@ -21,8 +21,7 @@ class CTkLabel(CTkBaseClass):
# transfer basic functionality (bg_color, size, _appearance_mode, scaling) to CTkBaseClass
if "master" in kwargs:
super().__init__(*args, bg_color=bg_color, width=width, height=height, master=kwargs["master"])
del kwargs["master"]
super().__init__(*args, bg_color=bg_color, width=width, height=height, master=kwargs.pop("master"))
else:
super().__init__(*args, bg_color=bg_color, width=width, height=height)
@ -107,9 +106,7 @@ class CTkLabel(CTkBaseClass):
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self._appearance_mode))
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
def configure(self, require_redraw=False, **kwargs):
if "anchor" in kwargs:
self.anchor = kwargs.pop("anchor")
text_label_grid_sticky = self.anchor if self.anchor != "center" else ""
@ -125,14 +122,6 @@ class CTkLabel(CTkBaseClass):
require_redraw = True
del kwargs["fg_color"]
if "bg_color" in kwargs:
if kwargs["bg_color"] is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = kwargs["bg_color"]
require_redraw = True
del kwargs["bg_color"]
if "text_color" in kwargs:
self.text_color = kwargs["text_color"]
require_redraw = True
@ -146,10 +135,12 @@ class CTkLabel(CTkBaseClass):
self.set_dimensions(height=kwargs["height"])
del kwargs["height"]
self.text_label.configure(*args, **kwargs)
if "bg_color" in kwargs:
super().configure(bg_color=kwargs.pop("bg_color"), require_redraw=require_redraw)
else:
super().configure(require_redraw=require_redraw)
if require_redraw:
self.draw()
self.text_label.configure(**kwargs) # pass remaining kwargs to label
def set_text(self, text):
self.text = text

View File

@ -189,9 +189,7 @@ class CTkOptionMenu(CTkBaseClass):
self.dropdown_menu.open(self.winfo_rootx(),
self.winfo_rooty() + self.apply_widget_scaling(self._current_height + 0))
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
def configure(self, require_redraw=False, **kwargs):
if "state" in kwargs:
self.state = kwargs.pop("state")
require_redraw = True
@ -200,14 +198,6 @@ class CTkOptionMenu(CTkBaseClass):
self.fg_color = kwargs.pop("fg_color")
require_redraw = True
if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = new_bg_color
require_redraw = True
if "button_color" in kwargs:
self.button_color = kwargs.pop("button_color")
require_redraw = True
@ -264,10 +254,7 @@ class CTkOptionMenu(CTkBaseClass):
else:
self.grid_propagate(1)
super().configure(*args, **kwargs)
if require_redraw:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)
def on_enter(self, event=0):
if self.hover is True and self.state == tkinter.NORMAL and len(self.values) > 0:

View File

@ -120,17 +120,7 @@ class CTkProgressBar(CTkBaseClass):
fill=ThemeManager.single_color(self.progress_color, self._appearance_mode),
outline=ThemeManager.single_color(self.progress_color, self._appearance_mode))
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
if "bg_color" in kwargs:
if kwargs["bg_color"] is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = kwargs["bg_color"]
require_redraw = True
del kwargs["bg_color"]
def configure(self, require_redraw=False, **kwargs):
if "fg_color" in kwargs:
self.fg_color = kwargs["fg_color"]
del kwargs["fg_color"]
@ -173,10 +163,7 @@ class CTkProgressBar(CTkBaseClass):
self.set_dimensions(height=kwargs["height"])
del kwargs["height"]
super().configure(*args, **kwargs)
if require_redraw is True:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)
def variable_callback(self, var_name, index, mode):
if not self.variable_callback_blocked:

View File

@ -151,9 +151,7 @@ class CTkRadioButton(CTkBaseClass):
self.text_label.configure(bg=ThemeManager.single_color(self.bg_color, self._appearance_mode))
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw()
def configure(self, require_redraw=False, **kwargs):
if "text" in kwargs:
self.text = kwargs.pop("text")
self.text_label.configure(text=self.text)
@ -167,14 +165,6 @@ class CTkRadioButton(CTkBaseClass):
self.fg_color = kwargs.pop("fg_color")
require_redraw = True
if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = new_bg_color
require_redraw = True
if "hover_color" in kwargs:
self.hover_color = kwargs.pop("hover_color")
require_redraw = True
@ -209,10 +199,7 @@ class CTkRadioButton(CTkBaseClass):
self.check_state = True if self.variable.get() == self.value else False
require_redraw = True
super().configure(*args, **kwargs)
if require_redraw:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)
def set_cursor(self):
if Settings.cursor_manipulation_enabled:

View File

@ -148,17 +148,7 @@ class CTkScrollbar(CTkBaseClass):
def get(self):
return self.start_value, self.end_value
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
if "bg_color" in kwargs:
if kwargs["bg_color"] is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = kwargs["bg_color"]
require_redraw = True
del kwargs["bg_color"]
def configure(self, require_redraw=False, **kwargs):
if "fg_color" in kwargs:
self.fg_color = kwargs["fg_color"]
require_redraw = True
@ -196,10 +186,7 @@ class CTkScrollbar(CTkBaseClass):
self.set_dimensions(height=kwargs["height"])
del kwargs["height"]
super().configure(*args, **kwargs)
if require_redraw:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)
def on_enter(self, event=0):
if self.hover is True:

View File

@ -258,9 +258,7 @@ class CTkSlider(CTkBaseClass):
if not self.variable_callback_blocked:
self.set(self.variable.get(), from_variable_callback=True)
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
def configure(self, require_redraw=False, **kwargs):
if "state" in kwargs:
self.state = kwargs["state"]
self.set_cursor()
@ -272,14 +270,6 @@ class CTkSlider(CTkBaseClass):
require_redraw = True
del kwargs["fg_color"]
if "bg_color" in kwargs:
if kwargs["bg_color"] is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = kwargs["bg_color"]
require_redraw = True
del kwargs["bg_color"]
if "progress_color" in kwargs:
if kwargs["progress_color"] is None:
self.progress_color = self.fg_color
@ -346,7 +336,4 @@ class CTkSlider(CTkBaseClass):
self.set_dimensions(height=kwargs["height"])
del kwargs["height"]
super().configure(*args, **kwargs)
if require_redraw:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)

View File

@ -267,9 +267,7 @@ class CTkSwitch(CTkBaseClass):
elif self.variable.get() == self.offvalue:
self.deselect(from_variable_callback=True)
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
def configure(self, require_redraw=False, **kwargs):
if "text" in kwargs:
self.text = kwargs.pop("text")
self.text_label.configure(text=self.text)
@ -283,14 +281,6 @@ class CTkSwitch(CTkBaseClass):
self.fg_color = kwargs.pop("fg_color")
require_redraw = True
if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = new_bg_color
require_redraw = True
if "progress_color" in kwargs:
new_progress_color = kwargs.pop("progress_color")
if new_progress_color is None:
@ -335,7 +325,4 @@ class CTkSwitch(CTkBaseClass):
else:
self.variable = None
super().configure(*args, **kwargs)
if require_redraw:
self.draw()
super().configure(require_redraw=require_redraw, **kwargs)

View File

@ -20,7 +20,10 @@ class CTkTextbox(CTkBaseClass):
**kwargs):
# transfer basic functionality (bg_color, size, _appearance_mode, scaling) to CTkBaseClass
super().__init__(*args, bg_color=bg_color, width=width, height=height)
if "master" in kwargs:
super().__init__(*args, bg_color=bg_color, width=width, height=height, master=kwargs.pop("master"))
else:
super().__init__(*args, bg_color=bg_color, width=width, height=height)
# color
self.fg_color = ThemeManager.theme["color"]["entry"] if fg_color == "default_theme" else fg_color
@ -45,7 +48,7 @@ class CTkTextbox(CTkBaseClass):
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self._appearance_mode))
self.draw_engine = DrawEngine(self.canvas)
for arg in ["highlightthickness", "fg", "bg"]:
for arg in ["highlightthickness", "fg", "bg", "font", "width", "height"]:
kwargs.pop(arg, None)
self.textbox = tkinter.Text(self,
fg=ThemeManager.single_color(self.text_color, self._appearance_mode),
@ -119,9 +122,7 @@ class CTkTextbox(CTkBaseClass):
def insert(self, args, kwargs):
self.textbox.insert(args, kwargs)
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
def configure(self, require_redraw=False, **kwargs):
if "fg_color" in kwargs:
self.fg_color = kwargs.pop("fg_color")
require_redraw = True
@ -131,14 +132,6 @@ class CTkTextbox(CTkBaseClass):
if isinstance(child, CTkBaseClass):
child.configure(bg_color=self.fg_color)
if "bg_color" in kwargs:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = new_bg_color
require_redraw = True
if "border_color" in kwargs:
self.border_color = kwargs.pop("border_color")
require_redraw = True
@ -157,7 +150,9 @@ class CTkTextbox(CTkBaseClass):
if "height" in kwargs:
self.set_dimensions(height=kwargs.pop("height"))
self.textbox.configure(*args, **kwargs)
if "bg_color" in kwargs:
super().configure(bg_color=kwargs.pop("bg_color"), require_redraw=require_redraw)
else:
super().configure(require_redraw=require_redraw)
if require_redraw:
self.draw()
self.textbox.configure(**kwargs)

View File

@ -116,23 +116,18 @@ class CTkBaseClass(tkinter.Frame):
return scaled_kwargs
def config(self, *args, **kwargs):
self.configure(*args, **kwargs)
def configure(self, *args, **kwargs):
def configure(self, require_redraw=False, **kwargs):
""" basic configure with bg_color support, to be overridden """
require_redraw = False
if "bg_color" in kwargs:
if kwargs["bg_color"] is None:
new_bg_color = kwargs.pop("bg_color")
if new_bg_color is None:
self.bg_color = self.detect_color_of_master()
else:
self.bg_color = kwargs["bg_color"]
self.bg_color = new_bg_color
require_redraw = True
del kwargs["bg_color"]
super().configure(*args, **kwargs)
super().configure(**kwargs)
if require_redraw:
self.draw()