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 tkinter
|
||||||
import customtkinter # <- import the CustomTkinter module
|
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.geometry("400x240")
|
||||||
root_tk.title("CustomTkinter Test")
|
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
|
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:
|
colors and removed the round corners, and added a border to the buttons:
|
||||||
|
|
||||||

|

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