mirror of
https://github.com/TomSchimansky/CustomTkinter.git
synced 2023-08-10 21:13:13 +03:00
added tkinter variables to all possible CTk widgets
This commit is contained in:
parent
587a597e6b
commit
6eb0d92ddd
28
Readme.md
28
Readme.md
@ -35,7 +35,7 @@ To test customtkinter you can try this simple example with only a single button:
|
||||
import tkinter
|
||||
import customtkinter # <- import the CustomTkinter module
|
||||
|
||||
root_tk = customtkinter.CTk() # create CTk window like you do with the Tk window (you can also use normal tkinter.Tk window)
|
||||
root_tk = customtkinter.CTk() # create CTk window like you do with the Tk window (tkinter.Tk has less functionality)
|
||||
root_tk.geometry("400x240")
|
||||
root_tk.title("CustomTkinter Test")
|
||||
|
||||
@ -108,7 +108,7 @@ With macOS dark-mode turned on, it looks like this:
|
||||
But you can also customize it by yourself. Here I changed the main
|
||||
colors and removed the round corners, and added a border to the buttons:
|
||||
|
||||

|
||||

|
||||
|
||||
### Default color themes
|
||||
|
||||
@ -138,7 +138,7 @@ Example 1:```examples/complex_example.py```
|
||||
|
||||

|
||||
|
||||
Example 2: ```examples/complex_example_other_style.py```
|
||||
Example 2: ```examples/complex_example_custom_colors.py```
|
||||
|
||||

|
||||
|
||||
@ -180,7 +180,7 @@ root_tk = customtkinter.CTk()
|
||||
root_tk.mainloop()
|
||||
```
|
||||
<details>
|
||||
<summary>Show all arguments:</summary>
|
||||
<summary>Show all arguments and methods:</summary>
|
||||
|
||||
argument | value
|
||||
--- | ---
|
||||
@ -206,7 +206,7 @@ frame = customtkinter.CTkFrame(master=root_tk,
|
||||
frame.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
|
||||
```
|
||||
<details>
|
||||
<summary>Show all arguments:</summary>
|
||||
<summary>Show all arguments and methods:</summary>
|
||||
|
||||
argument | value
|
||||
--- | ---
|
||||
@ -233,13 +233,14 @@ button = customtkinter.CTkButton(master=root_tk,
|
||||
button.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
|
||||
```
|
||||
<details>
|
||||
<summary>Show all arguments:</summary>
|
||||
<summary>Show all arguments and methods:</summary>
|
||||
|
||||
argument | value
|
||||
--- | ---
|
||||
master | root, tkinter.Frame or CTkFrame
|
||||
text | string
|
||||
command | callback function
|
||||
textvariable | tkinter.StringVar object to change text of button
|
||||
text | string
|
||||
width | button width in px
|
||||
height | button height in px
|
||||
corner_radius | corner radius in px
|
||||
@ -283,11 +284,12 @@ label = customtkinter.CTkLabel(master=root_tk,
|
||||
label.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
|
||||
```
|
||||
<details>
|
||||
<summary>Show all arguments:</summary>
|
||||
<summary>Show all arguments and methods:</summary>
|
||||
|
||||
argument | value
|
||||
--- | ---
|
||||
master | root, tkinter.Frame or CTkFrame
|
||||
variable | tkinter.StringVar object
|
||||
text | string
|
||||
width | label width in px
|
||||
height | label height in px
|
||||
@ -320,11 +322,12 @@ entry.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
|
||||
text = entry.get()
|
||||
```
|
||||
<details>
|
||||
<summary>Show all arguments:</summary>
|
||||
<summary>Show all arguments and methods:</summary>
|
||||
|
||||
argument | value
|
||||
--- | ---
|
||||
master | root, tkinter.Frame or CTkFrame
|
||||
variable | tkinter.StringVar object
|
||||
width | entry width in px
|
||||
height | entry height in px
|
||||
corner_radius | corner radius in px
|
||||
@ -352,7 +355,7 @@ checkbox = customtkinter.CTkCheckBox(master=root_tk,
|
||||
checkbox.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
|
||||
```
|
||||
<details>
|
||||
<summary>Show all arguments:</summary>
|
||||
<summary>Show all arguments and methods:</summary>
|
||||
|
||||
argument | value
|
||||
--- | ---
|
||||
@ -405,12 +408,13 @@ slider = customtkinter.CTkSlider(master=root_tk,
|
||||
slider.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
|
||||
```
|
||||
<details>
|
||||
<summary>Show all arguments:</summary>
|
||||
<summary>Show all arguments and methods:</summary>
|
||||
|
||||
argument | value
|
||||
--- | ---
|
||||
master | root, tkinter.Frame or CTkFrame
|
||||
command | callback function, gest called when slider gets changed
|
||||
variable | tkinter.IntVar or tkinter.DoubleVar object
|
||||
width | slider width in px
|
||||
height | slider height in px
|
||||
from_ | lower slider value
|
||||
@ -444,7 +448,7 @@ progressbar.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
|
||||
progressbar.set(value)
|
||||
```
|
||||
<details>
|
||||
<summary>Show all arguments:</summary>
|
||||
<summary>Show all arguments and methods:</summary>
|
||||
|
||||
argument | value
|
||||
--- | ---
|
||||
|
@ -10,7 +10,7 @@ from .customtkinter_dialog import CTkDialog
|
||||
from .customtkinter_checkbox import CTkCheckBox
|
||||
from .customtkinter_tk import CTk
|
||||
|
||||
from .appearance_mode_tracker import AppearanceModeTracker#, SystemAppearanceModeListenerNoThread
|
||||
from .appearance_mode_tracker import AppearanceModeTracker
|
||||
from .customtkinter_color_manager import CTkColorManager
|
||||
|
||||
from distutils.version import StrictVersion as Version
|
||||
|
@ -11,13 +11,14 @@ from .customtkinter_color_manager import CTkColorManager
|
||||
class CTkButton(tkinter.Frame):
|
||||
""" tkinter custom button with border, rounded corners and hover effect """
|
||||
|
||||
def __init__(self,
|
||||
def __init__(self, *args,
|
||||
bg_color=None,
|
||||
fg_color="CTkColorManager",
|
||||
hover_color="CTkColorManager",
|
||||
border_color=None,
|
||||
border_width=0,
|
||||
command=None,
|
||||
textvariable=None,
|
||||
width=120,
|
||||
height=30,
|
||||
corner_radius=8,
|
||||
@ -28,7 +29,7 @@ class CTkButton(tkinter.Frame):
|
||||
image=None,
|
||||
compound=tkinter.LEFT,
|
||||
state=tkinter.NORMAL,
|
||||
*args, **kwargs):
|
||||
**kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget too
|
||||
@ -92,6 +93,7 @@ class CTkButton(tkinter.Frame):
|
||||
self.text_font = text_font
|
||||
|
||||
self.function = command
|
||||
self.textvariable = textvariable
|
||||
self.state = state
|
||||
self.hover = hover
|
||||
self.image = image
|
||||
@ -209,7 +211,7 @@ class CTkButton(tkinter.Frame):
|
||||
if self.text is not None and self.text != "":
|
||||
|
||||
if self.text_label is None:
|
||||
self.text_label = tkinter.Label(master=self, font=self.text_font)
|
||||
self.text_label = tkinter.Label(master=self, font=self.text_font, textvariable=self.textvariable)
|
||||
|
||||
self.text_label.bind("<Enter>", self.on_enter)
|
||||
self.text_label.bind("<Leave>", self.on_leave)
|
||||
@ -490,6 +492,12 @@ class CTkButton(tkinter.Frame):
|
||||
self.function = kwargs["command"]
|
||||
del kwargs["command"]
|
||||
|
||||
if "textvariable" in kwargs:
|
||||
self.textvariable = kwargs["textvariable"]
|
||||
if self.text_label is not None:
|
||||
self.text_label.configure(textvariable=self.textvariable)
|
||||
del kwargs["textvariable"]
|
||||
|
||||
super().configure(*args, **kwargs)
|
||||
|
||||
if require_redraw:
|
||||
|
@ -10,7 +10,7 @@ from .customtkinter_color_manager import CTkColorManager
|
||||
class CTkCheckBox(tkinter.Frame):
|
||||
""" tkinter custom checkbox with border, rounded corners and hover effect """
|
||||
|
||||
def __init__(self,
|
||||
def __init__(self, *args,
|
||||
bg_color=None,
|
||||
fg_color="CTkColorManager",
|
||||
hover_color="CTkColorManager",
|
||||
@ -25,7 +25,11 @@ class CTkCheckBox(tkinter.Frame):
|
||||
hover=True,
|
||||
command=None,
|
||||
state=tkinter.NORMAL,
|
||||
*args, **kwargs):
|
||||
onvalue=1,
|
||||
offvalue=0,
|
||||
variable=None,
|
||||
textvariable=None,
|
||||
**kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget too
|
||||
@ -89,6 +93,12 @@ class CTkCheckBox(tkinter.Frame):
|
||||
self.state = state
|
||||
self.hover = hover
|
||||
self.check_state = False
|
||||
self.onvalue = onvalue
|
||||
self.offvalue = offvalue
|
||||
self.variable: tkinter.Variable = variable
|
||||
self.variable_callback_blocked = False
|
||||
self.textvariable = textvariable
|
||||
self.variabel_callback_name = None
|
||||
|
||||
self.canvas = tkinter.Canvas(master=self,
|
||||
highlightthicknes=0,
|
||||
@ -111,10 +121,21 @@ class CTkCheckBox(tkinter.Frame):
|
||||
self.canvas_check_parts = []
|
||||
self.text_label = None
|
||||
|
||||
self.draw()
|
||||
self.draw() # initial draw
|
||||
|
||||
if self.variable is not None:
|
||||
self.variabel_callback_name = self.variable.trace_add("write", self.variable_callback)
|
||||
if self.variable.get() == self.onvalue:
|
||||
self.select(from_variable_callback=True)
|
||||
elif self.variable.get() == self.offvalue:
|
||||
self.deselect(from_variable_callback=True)
|
||||
|
||||
def destroy(self):
|
||||
AppearanceModeTracker.remove(self.set_appearance_mode)
|
||||
|
||||
if self.variable is not None:
|
||||
self.variable.trace_remove("write", self.variabel_callback_name)
|
||||
|
||||
super().destroy()
|
||||
|
||||
def detect_color_of_master(self):
|
||||
@ -300,6 +321,23 @@ class CTkCheckBox(tkinter.Frame):
|
||||
self.function = kwargs["command"]
|
||||
del kwargs["command"]
|
||||
|
||||
if "variable" in kwargs:
|
||||
if self.variable is not None:
|
||||
self.variable.trace_remove("write", self.variabel_callback_name)
|
||||
|
||||
self.variable = kwargs["variable"]
|
||||
|
||||
if self.variable is not None and self.variable != "":
|
||||
self.variabel_callback_name = self.variable.trace_add("write", self.variable_callback)
|
||||
if self.variable.get() == self.onvalue:
|
||||
self.select(from_variable_callback=True)
|
||||
elif self.variable.get() == self.offvalue:
|
||||
self.deselect(from_variable_callback=True)
|
||||
else:
|
||||
self.variable = None
|
||||
|
||||
del kwargs["variable"]
|
||||
|
||||
super().configure(*args, **kwargs)
|
||||
|
||||
if require_redraw:
|
||||
@ -350,6 +388,13 @@ class CTkCheckBox(tkinter.Frame):
|
||||
else:
|
||||
self.canvas.itemconfig(part, fill=self.bg_color, width=0)
|
||||
|
||||
def variable_callback(self, var_name, index, mode):
|
||||
if not self.variable_callback_blocked:
|
||||
if self.variable.get() == self.onvalue:
|
||||
self.select(from_variable_callback=True)
|
||||
elif self.variable.get() == self.offvalue:
|
||||
self.deselect(from_variable_callback=True)
|
||||
|
||||
def toggle(self, event=0):
|
||||
if self.state == tkinter.NORMAL:
|
||||
if self.check_state is True:
|
||||
@ -370,7 +415,12 @@ class CTkCheckBox(tkinter.Frame):
|
||||
if self.function is not None:
|
||||
self.function()
|
||||
|
||||
def select(self):
|
||||
if self.variable is not None:
|
||||
self.variable_callback_blocked = True
|
||||
self.variable.set(self.onvalue if self.check_state is True else self.offvalue)
|
||||
self.variable_callback_blocked = False
|
||||
|
||||
def select(self, from_variable_callback=False):
|
||||
self.check_state = True
|
||||
for part in self.canvas_fg_parts:
|
||||
if type(self.fg_color) == tuple and len(self.fg_color) == 2:
|
||||
@ -381,7 +431,12 @@ class CTkCheckBox(tkinter.Frame):
|
||||
if self.function is not None:
|
||||
self.function()
|
||||
|
||||
def deselect(self):
|
||||
if self.variable is not None and not from_variable_callback:
|
||||
self.variable_callback_blocked = True
|
||||
self.variable.set(self.onvalue)
|
||||
self.variable_callback_blocked = False
|
||||
|
||||
def deselect(self, from_variable_callback=False):
|
||||
self.check_state = False
|
||||
for part in self.canvas_fg_parts:
|
||||
if type(self.bg_color) == tuple and len(self.bg_color) == 2:
|
||||
@ -392,8 +447,13 @@ class CTkCheckBox(tkinter.Frame):
|
||||
if self.function is not None:
|
||||
self.function()
|
||||
|
||||
if self.variable is not None and not from_variable_callback:
|
||||
self.variable_callback_blocked = True
|
||||
self.variable.set(self.offvalue)
|
||||
self.variable_callback_blocked = False
|
||||
|
||||
def get(self):
|
||||
return 1 if self.check_state is True else 0
|
||||
return self.onvalue if self.check_state is True else self.offvalue
|
||||
|
||||
def set_appearance_mode(self, mode_string):
|
||||
if mode_string.lower() == "dark":
|
||||
|
@ -8,7 +8,7 @@ from .customtkinter_color_manager import CTkColorManager
|
||||
|
||||
|
||||
class CTkEntry(tkinter.Frame):
|
||||
def __init__(self,
|
||||
def __init__(self, *args,
|
||||
master=None,
|
||||
bg_color=None,
|
||||
fg_color="CTkColorManager",
|
||||
@ -16,9 +16,11 @@ class CTkEntry(tkinter.Frame):
|
||||
corner_radius=8,
|
||||
width=120,
|
||||
height=30,
|
||||
*args,
|
||||
**kwargs):
|
||||
super().__init__(master=master)
|
||||
if master is None:
|
||||
super().__init__(*args)
|
||||
else:
|
||||
super().__init__(*args, master=master)
|
||||
|
||||
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget too
|
||||
if isinstance(self.master, (tkinter.Tk, tkinter.Frame)) and not isinstance(self.master, (CTk, CTkFrame)):
|
||||
@ -58,7 +60,7 @@ class CTkEntry(tkinter.Frame):
|
||||
elif self.corner_radius*2 > self.width:
|
||||
self.corner_radius = self.width/2
|
||||
|
||||
self.configure(width=self.width, height=self.height)
|
||||
super().configure(width=self.width, height=self.height)
|
||||
|
||||
self.canvas = tkinter.Canvas(master=self,
|
||||
highlightthicknes=0,
|
||||
@ -69,7 +71,7 @@ class CTkEntry(tkinter.Frame):
|
||||
self.entry = tkinter.Entry(master=self,
|
||||
bd=0,
|
||||
highlightthicknes=0,
|
||||
*args, **kwargs)
|
||||
**kwargs)
|
||||
self.entry.place(relx=0.5, rely=0.5, relwidth=0.8, anchor=tkinter.CENTER)
|
||||
|
||||
self.fg_parts = []
|
||||
@ -184,7 +186,7 @@ class CTkEntry(tkinter.Frame):
|
||||
del kwargs["corner_radius"]
|
||||
require_redraw = True
|
||||
|
||||
super().configure(*args, **kwargs)
|
||||
self.entry.configure(*args, **kwargs)
|
||||
|
||||
if require_redraw is True:
|
||||
self.draw()
|
||||
|
@ -8,7 +8,7 @@ from .customtkinter_color_manager import CTkColorManager
|
||||
|
||||
|
||||
class CTkLabel(tkinter.Frame):
|
||||
def __init__(self,
|
||||
def __init__(self, *args,
|
||||
master=None,
|
||||
bg_color=None,
|
||||
fg_color="CTkColorManager",
|
||||
@ -18,9 +18,11 @@ class CTkLabel(tkinter.Frame):
|
||||
height=25,
|
||||
text="CTkLabel",
|
||||
text_font=None,
|
||||
*args,
|
||||
**kwargs):
|
||||
super().__init__(master=master)
|
||||
if master is None:
|
||||
super().__init__(*args)
|
||||
else:
|
||||
super().__init__(*args, master=master)
|
||||
|
||||
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget too
|
||||
if isinstance(self.master, (tkinter.Tk, tkinter.Frame)) and not isinstance(self.master, (CTk, CTkFrame)):
|
||||
@ -71,7 +73,6 @@ class CTkLabel(tkinter.Frame):
|
||||
self.text_font = ("TkDefaultFont", 10)
|
||||
else:
|
||||
self.text_font = text_font
|
||||
self.configure(width=self.width, height=self.height)
|
||||
|
||||
self.canvas = tkinter.Canvas(master=self,
|
||||
highlightthicknes=0,
|
||||
@ -84,11 +85,13 @@ class CTkLabel(tkinter.Frame):
|
||||
bd=0,
|
||||
text=self.text,
|
||||
font=self.text_font,
|
||||
*args, **kwargs)
|
||||
**kwargs)
|
||||
self.text_label.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
|
||||
|
||||
self.fg_parts = []
|
||||
|
||||
super().configure(width=self.width, height=self.height)
|
||||
|
||||
self.draw()
|
||||
|
||||
def destroy(self):
|
||||
@ -202,7 +205,7 @@ class CTkLabel(tkinter.Frame):
|
||||
require_redraw = True
|
||||
del kwargs["text_color"]
|
||||
|
||||
super().configure(*args, **kwargs)
|
||||
self.text_label.configure(*args, **kwargs)
|
||||
|
||||
if require_redraw:
|
||||
self.draw()
|
||||
|
@ -10,7 +10,8 @@ from .customtkinter_color_manager import CTkColorManager
|
||||
class CTkProgressBar(tkinter.Frame):
|
||||
""" tkinter custom progressbar, always horizontal, values are from 0 to 1 """
|
||||
|
||||
def __init__(self,
|
||||
def __init__(self, *args,
|
||||
variable=None,
|
||||
bg_color=None,
|
||||
border_color="CTkColorManager",
|
||||
fg_color="CTkColorManager",
|
||||
@ -18,7 +19,7 @@ class CTkProgressBar(tkinter.Frame):
|
||||
width=160,
|
||||
height=10,
|
||||
border_width=0,
|
||||
*args, **kwargs):
|
||||
**kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget too
|
||||
@ -50,6 +51,10 @@ class CTkProgressBar(tkinter.Frame):
|
||||
self.fg_color = CTkColorManager.PROGRESS_BG if fg_color == "CTkColorManager" else fg_color
|
||||
self.progress_color = CTkColorManager.MAIN if progress_color == "CTkColorManager" else progress_color
|
||||
|
||||
self.variable = variable
|
||||
self.variable_callback_blocked = False
|
||||
self.variabel_callback_name = None
|
||||
|
||||
self.width = width
|
||||
self.height = self.calc_optimal_height(height)
|
||||
self.border_width = round(border_width)
|
||||
@ -63,13 +68,20 @@ class CTkProgressBar(tkinter.Frame):
|
||||
height=self.height)
|
||||
self.canvas.place(x=0, y=0)
|
||||
|
||||
self.draw()
|
||||
self.draw() # initial draw
|
||||
|
||||
# set progress
|
||||
self.set(self.value)
|
||||
if self.variable is not None:
|
||||
self.variabel_callback_name = self.variable.trace_add("write", self.variable_callback)
|
||||
self.variable_callback_blocked = True
|
||||
self.set(self.variable.get(), from_variable_callback=True)
|
||||
self.variable_callback_blocked = False
|
||||
|
||||
def destroy(self):
|
||||
AppearanceModeTracker.remove(self.change_appearance_mode)
|
||||
|
||||
if self.variable is not None:
|
||||
self.variable.trace_remove("write", self.variabel_callback_name)
|
||||
|
||||
super().destroy()
|
||||
|
||||
def detect_color_of_master(self):
|
||||
@ -252,12 +264,30 @@ class CTkProgressBar(tkinter.Frame):
|
||||
del kwargs["border_width"]
|
||||
require_redraw = True
|
||||
|
||||
if "variable" in kwargs:
|
||||
if self.variable is not None:
|
||||
self.variable.trace_remove("write", self.variabel_callback_name)
|
||||
|
||||
self.variable = kwargs["variable"]
|
||||
|
||||
if self.variable is not None and self.variable != "":
|
||||
self.variabel_callback_name = self.variable.trace_add("write", self.variable_callback)
|
||||
self.set(self.variable.get(), from_variable_callback=True)
|
||||
else:
|
||||
self.variable = None
|
||||
|
||||
del kwargs["variable"]
|
||||
|
||||
super().configure(*args, **kwargs)
|
||||
|
||||
if require_redraw is True:
|
||||
self.draw()
|
||||
|
||||
def set(self, value):
|
||||
def variable_callback(self, var_name, index, mode):
|
||||
if not self.variable_callback_blocked:
|
||||
self.set(self.variable.get(), from_variable_callback=True)
|
||||
|
||||
def set(self, value, from_variable_callback=False):
|
||||
self.value = value
|
||||
|
||||
if self.value > 1:
|
||||
@ -267,6 +297,11 @@ class CTkProgressBar(tkinter.Frame):
|
||||
|
||||
self.draw(no_color_updates=True)
|
||||
|
||||
if self.variable is not None and not from_variable_callback:
|
||||
self.variable_callback_blocked = True
|
||||
self.variable.set(round(self.value) if isinstance(self.variable, tkinter.IntVar) else self.value)
|
||||
self.variable_callback_blocked = False
|
||||
|
||||
def change_appearance_mode(self, mode_string):
|
||||
if mode_string.lower() == "dark":
|
||||
self.appearance_mode = 1
|
||||
|
@ -10,7 +10,7 @@ from .customtkinter_color_manager import CTkColorManager
|
||||
class CTkSlider(tkinter.Frame):
|
||||
""" tkinter custom slider, always horizontal """
|
||||
|
||||
def __init__(self,
|
||||
def __init__(self, *args,
|
||||
bg_color=None,
|
||||
border_color=None,
|
||||
fg_color="CTkColorManager",
|
||||
@ -24,7 +24,8 @@ class CTkSlider(tkinter.Frame):
|
||||
height=16,
|
||||
border_width=5,
|
||||
command=None,
|
||||
*args, **kwargs):
|
||||
variable=None,
|
||||
**kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# overwrite configure methods of master when master is tkinter widget, so that bg changes get applied on child CTk widget too
|
||||
@ -56,12 +57,11 @@ class CTkSlider(tkinter.Frame):
|
||||
self.fg_color = CTkColorManager.SLIDER_BG if fg_color == "CTkColorManager" else fg_color
|
||||
self.progress_color = CTkColorManager.SLIDER_PROGRESS if progress_color == "CTkColorManager" else progress_color
|
||||
self.button_color = CTkColorManager.MAIN if button_color == "CTkColorManager" else button_color
|
||||
self.button_hover_color = CTkColorManager.MAIN if button_hover_color == "CTkColorManager" else button_hover_color
|
||||
self.button_hover_color = CTkColorManager.MAIN_HOVER if button_hover_color == "CTkColorManager" else button_hover_color
|
||||
|
||||
self.width = width
|
||||
self.height = self.calc_optimal_height(height)
|
||||
self.border_width = round(border_width)
|
||||
self.callback_function = command
|
||||
self.value = 0.5 # initial value of slider in percent
|
||||
self.hover_state = False
|
||||
self.from_ = from_
|
||||
@ -69,6 +69,11 @@ class CTkSlider(tkinter.Frame):
|
||||
self.number_of_steps = number_of_steps
|
||||
self.output_value = self.from_ + (self.value * (self.to - self.from_))
|
||||
|
||||
self.callback_function = command
|
||||
self.variable: tkinter.Variable = variable
|
||||
self.variable_callback_blocked = False
|
||||
self.variabel_callback_name = None
|
||||
|
||||
self.configure(width=self.width, height=self.height)
|
||||
if sys.platform == "darwin":
|
||||
self.configure(cursor="pointinghand")
|
||||
@ -84,10 +89,22 @@ class CTkSlider(tkinter.Frame):
|
||||
self.canvas.bind("<Button-1>", self.clicked)
|
||||
self.canvas.bind("<B1-Motion>", self.clicked)
|
||||
|
||||
self.draw()
|
||||
self.draw() # initial draw
|
||||
|
||||
if self.variable is not None:
|
||||
self.variabel_callback_name = self.variable.trace_add("write", self.variable_callback)
|
||||
self.variable_callback_blocked = True
|
||||
self.set(self.variable.get(), from_variable_callback=True)
|
||||
self.variable_callback_blocked = False
|
||||
|
||||
def destroy(self):
|
||||
# remove change_appearance_mode function from callback list of AppearanceModeTracker
|
||||
AppearanceModeTracker.remove(self.change_appearance_mode)
|
||||
|
||||
# remove variabel_callback from variable callbacks if variable exists
|
||||
if self.variable is not None:
|
||||
self.variable.trace_remove("write", self.variabel_callback_name)
|
||||
|
||||
super().destroy()
|
||||
|
||||
def detect_color_of_master(self):
|
||||
@ -292,6 +309,11 @@ class CTkSlider(tkinter.Frame):
|
||||
if self.callback_function is not None:
|
||||
self.callback_function(self.output_value)
|
||||
|
||||
if self.variable is not None:
|
||||
self.variable_callback_blocked = True
|
||||
self.variable.set(round(self.output_value) if isinstance(self.variable, tkinter.IntVar) else self.output_value)
|
||||
self.variable_callback_blocked = False
|
||||
|
||||
def on_enter(self, event=0):
|
||||
self.hover_state = True
|
||||
self.canvas.itemconfig("button_parts", fill=CTkColorManager.single_color(self.button_hover_color, self.appearance_mode))
|
||||
@ -311,7 +333,7 @@ class CTkSlider(tkinter.Frame):
|
||||
def get(self):
|
||||
return self.output_value
|
||||
|
||||
def set(self, output_value):
|
||||
def set(self, output_value, from_variable_callback=False):
|
||||
if output_value > self.to:
|
||||
output_value = self.to
|
||||
elif output_value < self.from_:
|
||||
@ -325,6 +347,15 @@ class CTkSlider(tkinter.Frame):
|
||||
if self.callback_function is not None:
|
||||
self.callback_function(self.output_value)
|
||||
|
||||
if self.variable is not None and not from_variable_callback:
|
||||
self.variable_callback_blocked = True
|
||||
self.variable.set(round(self.output_value) if isinstance(self.variable, tkinter.IntVar) else self.output_value)
|
||||
self.variable_callback_blocked = False
|
||||
|
||||
def variable_callback(self, var_name, index, mode):
|
||||
if not self.variable_callback_blocked:
|
||||
self.set(self.variable.get(), from_variable_callback=True)
|
||||
|
||||
def config(self, *args, **kwargs):
|
||||
self.configure(*args, **kwargs)
|
||||
|
||||
@ -388,6 +419,20 @@ class CTkSlider(tkinter.Frame):
|
||||
self.callback_function = kwargs["command"]
|
||||
del kwargs["command"]
|
||||
|
||||
if "variable" in kwargs:
|
||||
if self.variable is not None:
|
||||
self.variable.trace_remove("write", self.variabel_callback_name)
|
||||
|
||||
self.variable = kwargs["variable"]
|
||||
|
||||
if self.variable is not None and self.variable != "":
|
||||
self.variabel_callback_name = self.variable.trace_add("write", self.variable_callback)
|
||||
self.set(self.variable.get(), from_variable_callback=True)
|
||||
else:
|
||||
self.variable = None
|
||||
|
||||
del kwargs["variable"]
|
||||
|
||||
super().configure(*args, **kwargs)
|
||||
|
||||
if require_redraw:
|
||||
|
Before Width: | Height: | Size: 285 KiB After Width: | Height: | Size: 285 KiB |
@ -4,7 +4,7 @@ import customtkinter
|
||||
import sys
|
||||
|
||||
customtkinter.set_appearance_mode("System") # Other: "Light", "Dark"
|
||||
customtkinter.set_default_color_theme("green") # Themes: "blue" (standard), "green", "dark-blue"
|
||||
customtkinter.set_default_color_theme("dark-blue") # Themes: "blue" (standard), "green", "dark-blue"
|
||||
|
||||
|
||||
class App(customtkinter.CTk):
|
||||
|
Loading…
x
Reference in New Issue
Block a user