14 Commits

15 changed files with 56 additions and 49 deletions

View File

@ -17,6 +17,12 @@
--- ---
<div align="center">
<h3>
Official website: https://customtkinter.tomschimansky.com
</h3>
</div>
CustomTkinter is a python UI-library based on Tkinter, which provides new, modern and CustomTkinter is a python UI-library based on Tkinter, which provides new, modern and
fully customizable widgets. They are created and used like normal Tkinter widgets and fully customizable widgets. They are created and used like normal Tkinter widgets and
can also be used in combination with normal Tkinter elements. The widgets can also be used in combination with normal Tkinter elements. The widgets
@ -43,9 +49,9 @@ pip3 install customtkinter
## Documentation ## Documentation
The **official** documentation can be found in the Wiki Tab here: The **official** documentation can be found here:
**--> [Documentation](https://github.com/TomSchimansky/CustomTkinter/wiki)**. **➡️ https://customtkinter.tomschimansky.com/documentation**.
## Example Program ## Example Program
To test customtkinter you can try this simple example with only a single button: To test customtkinter you can try this simple example with only a single button:

View File

@ -1,4 +1,4 @@
__version__ = "5.1.1" __version__ = "5.1.3"
import os import os
import sys import sys

View File

@ -48,7 +48,7 @@
"corner_radius": 1000, "corner_radius": 1000,
"border_width": 3, "border_width": 3,
"button_length": 0, "button_length": 0,
"fg_Color": ["#939BA2", "#4A4D50"], "fg_color": ["#939BA2", "#4A4D50"],
"progress_color": ["#3B8ED0", "#1F6AA5"], "progress_color": ["#3B8ED0", "#1F6AA5"],
"button_color": ["gray36", "#D5D9DE"], "button_color": ["gray36", "#D5D9DE"],
"button_hover_color": ["gray20", "gray100"], "button_hover_color": ["gray20", "gray100"],

View File

@ -48,7 +48,7 @@
"corner_radius": 1000, "corner_radius": 1000,
"border_width": 3, "border_width": 3,
"button_length": 0, "button_length": 0,
"fg_Color": ["#939BA2", "#4A4D50"], "fg_color": ["#939BA2", "#4A4D50"],
"progress_color": ["#3a7ebf", "#1f538d"], "progress_color": ["#3a7ebf", "#1f538d"],
"button_color": ["gray36", "#D5D9DE"], "button_color": ["gray36", "#D5D9DE"],
"button_hover_color": ["gray20", "gray100"], "button_hover_color": ["gray20", "gray100"],
@ -127,6 +127,9 @@
"scrollbar_button_color": ["gray55", "gray41"], "scrollbar_button_color": ["gray55", "gray41"],
"scrollbar_button_hover_color": ["gray40", "gray53"] "scrollbar_button_hover_color": ["gray40", "gray53"]
}, },
"CTkScrollableFrame": {
"label_fg_color": ["gray80", "gray21"]
},
"DropdownMenu": { "DropdownMenu": {
"fg_color": ["gray90", "gray20"], "fg_color": ["gray90", "gray20"],
"hover_color": ["gray75", "gray28"], "hover_color": ["gray75", "gray28"],

View File

@ -48,7 +48,7 @@
"corner_radius": 1000, "corner_radius": 1000,
"border_width": 3, "border_width": 3,
"button_length": 0, "button_length": 0,
"fg_Color": ["#939BA2", "#4A4D50"], "fg_color": ["#939BA2", "#4A4D50"],
"progress_color": ["#2CC985", "#2FA572"], "progress_color": ["#2CC985", "#2FA572"],
"button_color": ["gray36", "#D5D9DE"], "button_color": ["gray36", "#D5D9DE"],
"button_hover_color": ["gray20", "gray100"], "button_hover_color": ["gray20", "gray100"],
@ -127,6 +127,9 @@
"scrollbar_button_color": ["gray55", "gray41"], "scrollbar_button_color": ["gray55", "gray41"],
"scrollbar_button_hover_color": ["gray40", "gray53"] "scrollbar_button_hover_color": ["gray40", "gray53"]
}, },
"CTkScrollableFrame": {
"label_fg_color": ["gray78", "gray23"]
},
"DropdownMenu": { "DropdownMenu": {
"fg_color": ["gray90", "gray20"], "fg_color": ["gray90", "gray20"],
"hover_color": ["gray75", "gray28"], "hover_color": ["gray75", "gray28"],

View File

@ -19,7 +19,7 @@ class CTkToplevel(tkinter.Toplevel, CTkAppearanceModeBaseClass, CTkScalingBaseCl
For detailed information check out the documentation. For detailed information check out the documentation.
""" """
_valid_tk_toplevel_arguments: set = {"bd", "borderwidth", "class", "container", "cursor", "height", _valid_tk_toplevel_arguments: set = {"master", "bd", "borderwidth", "class", "container", "cursor", "height",
"highlightbackground", "highlightthickness", "menu", "relief", "highlightbackground", "highlightthickness", "menu", "relief",
"screen", "takefocus", "use", "visual", "width"} "screen", "takefocus", "use", "visual", "width"}

View File

@ -14,6 +14,8 @@ class CTkLabel(CTkBaseClass):
""" """
Label with rounded corners. Default is fg_color=None (transparent fg_color). Label with rounded corners. Default is fg_color=None (transparent fg_color).
For detailed information check out the documentation. For detailed information check out the documentation.
state argument will probably be removed because it has no effect
""" """
# attributes that are passed to and managed by the tkinter entry only: # attributes that are passed to and managed by the tkinter entry only:

View File

@ -74,13 +74,7 @@ class CTkScrollableFrame(tkinter.Frame, CTkAppearanceModeBaseClass, CTkScalingBa
self.bind("<Configure>", lambda e: self._parent_canvas.configure(scrollregion=self._parent_canvas.bbox("all"))) self.bind("<Configure>", lambda e: self._parent_canvas.configure(scrollregion=self._parent_canvas.bbox("all")))
self._parent_canvas.bind("<Configure>", self._fit_frame_dimensions_to_canvas) self._parent_canvas.bind("<Configure>", self._fit_frame_dimensions_to_canvas)
if "linux" in sys.platform:
self.bind_all("<Button-4>", self._mouse_wheel_all, add="+")
self.bind_all("<Button-5>", self._mouse_wheel_all, add="+")
else:
self.bind_all("<MouseWheel>", self._mouse_wheel_all, add="+") self.bind_all("<MouseWheel>", self._mouse_wheel_all, add="+")
self.bind_all("<KeyPress-Shift_L>", self._keyboard_shift_press_all, add="+") self.bind_all("<KeyPress-Shift_L>", self._keyboard_shift_press_all, add="+")
self.bind_all("<KeyPress-Shift_R>", self._keyboard_shift_press_all, add="+") self.bind_all("<KeyPress-Shift_R>", self._keyboard_shift_press_all, add="+")
self.bind_all("<KeyRelease-Shift_L>", self._keyboard_shift_release_all, add="+") self.bind_all("<KeyRelease-Shift_L>", self._keyboard_shift_release_all, add="+")
@ -187,10 +181,10 @@ class CTkScrollableFrame(tkinter.Frame, CTkAppearanceModeBaseClass, CTkScalingBa
self._scrollbar.configure(fg_color=kwargs.pop("scrollbar_fg_color")) self._scrollbar.configure(fg_color=kwargs.pop("scrollbar_fg_color"))
if "scrollbar_button_color" in kwargs: if "scrollbar_button_color" in kwargs:
self._scrollbar.configure(fg_color=kwargs.pop("scrollbar_button_color")) self._scrollbar.configure(button_color=kwargs.pop("scrollbar_button_color"))
if "scrollbar_button_hover_color" in kwargs: if "scrollbar_button_hover_color" in kwargs:
self._scrollbar.configure(fg_color=kwargs.pop("scrollbar_button_hover_color")) self._scrollbar.configure(button_hover_color=kwargs.pop("scrollbar_button_hover_color"))
if "label_text" in kwargs: if "label_text" in kwargs:
self._label_text = kwargs.pop("label_text") self._label_text = kwargs.pop("label_text")
@ -249,8 +243,6 @@ class CTkScrollableFrame(tkinter.Frame, CTkAppearanceModeBaseClass, CTkScalingBa
self._parent_canvas.configure(xscrollincrement=1, yscrollincrement=1) self._parent_canvas.configure(xscrollincrement=1, yscrollincrement=1)
elif sys.platform == "darwin": elif sys.platform == "darwin":
self._parent_canvas.configure(xscrollincrement=4, yscrollincrement=8) self._parent_canvas.configure(xscrollincrement=4, yscrollincrement=8)
else:
self._parent_canvas.configure(xscrollincrement=30, yscrollincrement=30)
def _mouse_wheel_all(self, event): def _mouse_wheel_all(self, event):
if self.check_if_master_is_canvas(event.widget): if self.check_if_master_is_canvas(event.widget):
@ -271,11 +263,10 @@ class CTkScrollableFrame(tkinter.Frame, CTkAppearanceModeBaseClass, CTkScalingBa
else: else:
if self._shift_pressed: if self._shift_pressed:
if self._parent_canvas.xview() != (0.0, 1.0): if self._parent_canvas.xview() != (0.0, 1.0):
self._parent_canvas.xview_scroll(-1 if event.num == 4 else 1, "units") self._parent_canvas.xview("scroll", -event.delta, "units")
else: else:
if self._parent_canvas.yview() != (0.0, 1.0): if self._parent_canvas.yview() != (0.0, 1.0):
self._parent_canvas.yview_scroll(-1 if event.num == 4 else 1, "units") self._parent_canvas.yview("scroll", -event.delta, "units")
def _keyboard_shift_press_all(self, event): def _keyboard_shift_press_all(self, event):
self._shift_pressed = True self._shift_pressed = True

View File

@ -54,7 +54,7 @@ class CTkSwitch(CTkBaseClass):
# color # color
self._border_color = self._check_color_type(border_color, transparency=True) self._border_color = self._check_color_type(border_color, transparency=True)
self._fg_color = ThemeManager.theme["CTkSwitch"]["fg_Color"] if fg_color is None else self._check_color_type(fg_color) self._fg_color = ThemeManager.theme["CTkSwitch"]["fg_color"] if fg_color is None else self._check_color_type(fg_color)
self._progress_color = ThemeManager.theme["CTkSwitch"]["progress_color"] if progress_color is None else self._check_color_type(progress_color, transparency=True) self._progress_color = ThemeManager.theme["CTkSwitch"]["progress_color"] if progress_color is None else self._check_color_type(progress_color, transparency=True)
self._button_color = ThemeManager.theme["CTkSwitch"]["button_color"] if button_color is None else self._check_color_type(button_color) self._button_color = ThemeManager.theme["CTkSwitch"]["button_color"] if button_color is None else self._check_color_type(button_color)
self._button_hover_color = ThemeManager.theme["CTkSwitch"]["button_hover_color"] if button_hover_color is None else self._check_color_type(button_hover_color) self._button_hover_color = ThemeManager.theme["CTkSwitch"]["button_hover_color"] if button_hover_color is None else self._check_color_type(button_hover_color)
@ -299,6 +299,10 @@ class CTkSwitch(CTkBaseClass):
self._fg_color = self._check_color_type(kwargs.pop("fg_color")) self._fg_color = self._check_color_type(kwargs.pop("fg_color"))
require_redraw = True require_redraw = True
if "border_color" in kwargs:
self._border_color = self._check_color_type(kwargs.pop("border_color"), transparency=True)
require_redraw = True
if "progress_color" in kwargs: if "progress_color" in kwargs:
self._progress_color = self._check_color_type(kwargs.pop("progress_color"), transparency=True) self._progress_color = self._check_color_type(kwargs.pop("progress_color"), transparency=True)
require_redraw = True require_redraw = True
@ -311,8 +315,12 @@ class CTkSwitch(CTkBaseClass):
self._button_hover_color = self._check_color_type(kwargs.pop("button_hover_color")) self._button_hover_color = self._check_color_type(kwargs.pop("button_hover_color"))
require_redraw = True require_redraw = True
if "border_color" in kwargs: if "text_color" in kwargs:
self._border_color = self._check_color_type(kwargs.pop("border_color"), transparency=True) self._text_color = self._check_color_type(kwargs.pop("text_color"))
require_redraw = True
if "text_color_disabled" in kwargs:
self._text_color_disabled = self._check_color_type(kwargs.pop("text_color_disabled"))
require_redraw = True require_redraw = True
if "hover" in kwargs: if "hover" in kwargs:

View File

@ -99,9 +99,9 @@ class CTkTabview(CTkBaseClass):
self._draw() self._draw()
def _segmented_button_callback(self, selected_name): def _segmented_button_callback(self, selected_name):
self._set_grid_tab_by_name(selected_name)
self._tab_dict[self._current_name].grid_forget()
self._current_name = selected_name self._current_name = selected_name
self._grid_forget_all_tabs()
self._set_grid_tab_by_name(self._current_name)
if self._command is not None: if self._command is not None:
self._command() self._command()

View File

@ -4,6 +4,6 @@ from .theme_manager import ThemeManager
try: try:
ThemeManager.load_theme("blue") ThemeManager.load_theme("blue")
except FileNotFoundError as err: except FileNotFoundError as err:
raise FileNotFoundError(f"{err}\n\nThe .json theme file for CustomTkinter could not be found.\n" + raise FileNotFoundError(f"{err}\nThe .json theme file for CustomTkinter could not be found.\n" +
f"If packaging with pyinstaller was used, have a look at the wiki:\n" + f"If packaging with pyinstaller was used, have a look at the wiki:\n" +
f"https://github.com/TomSchimansky/CustomTkinter/wiki/Packaging#windows-pyinstaller-auto-py-to-exe") f"https://github.com/TomSchimansky/CustomTkinter/wiki/Packaging#windows-pyinstaller-auto-py-to-exe")

View File

@ -1,5 +1,6 @@
import sys import sys
import os import os
import pathlib
import json import json
from typing import List, Union from typing import List, Union
@ -15,7 +16,8 @@ class ThemeManager:
script_directory = os.path.dirname(os.path.abspath(__file__)) script_directory = os.path.dirname(os.path.abspath(__file__))
if theme_name_or_path in cls._built_in_themes: if theme_name_or_path in cls._built_in_themes:
with open(os.path.join(script_directory, "../../../assets", "themes", f"{theme_name_or_path}.json"), "r") as f: customtkinter_path = pathlib.Path(script_directory).parent.parent.parent
with open(os.path.join(customtkinter_path, "assets", "themes", f"{theme_name_or_path}.json"), "r") as f:
cls.theme = json.load(f) cls.theme = json.load(f)
else: else:
with open(theme_name_or_path, "r") as f: with open(theme_name_or_path, "r") as f:

View File

@ -3,11 +3,10 @@ requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
[tool.tbump] [tool.tbump]
# Uncomment this if your project is hosted on GitHub:
github_url = "https://github.com/TomSchimansky/CustomTkinter" github_url = "https://github.com/TomSchimansky/CustomTkinter"
[tool.tbump.version] [tool.tbump.version]
current = "5.1.1" current = "5.1.3"
# Example of a semver regexp. # Example of a semver regexp.
# Make sure this matches current_version before # Make sure this matches current_version before
@ -33,17 +32,3 @@ src = "setup.cfg"
[[tool.tbump.file]] [[tool.tbump.file]]
src = "customtkinter/__init__.py" src = "customtkinter/__init__.py"
search = "__version__ = \"{current_version}\"" search = "__version__ = \"{current_version}\""
# You can specify a list of commands to
# run after the files have been patched
# and before the git commit is made
# [[tool.tbump.before_commit]]
# name = "check changelog"
# cmd = "grep -q {new_version} Changelog.rst"
# Or run some commands after the git tag and the branch
# have been pushed:
# [[tool.tbump.after_push]]
# name = "publish"
# cmd = "./publish.sh"

View File

@ -1,10 +1,10 @@
[metadata] [project]
name = customtkinter name = customtkinter
version = 5.1.1 version = 5.1.3
description = Create modern looking GUIs with Python description = Create modern looking GUIs with Python
long_description = A modern and customizable python UI-library based on Tkinter: https://github.com/TomSchimansky/CustomTkinter long_description = A modern and customizable python UI-library based on Tkinter: https://customtkinter.tomschimansky.com
long_description_content_type = text/markdown long_description_content_type = text/markdown
url = https://github.com/TomSchimansky/CustomTkinter url = https://customtkinter.tomschimansky.com
author = Tom Schimansky author = Tom Schimansky
license = Creative Commons Zero v1.0 Universal license = Creative Commons Zero v1.0 Universal
license_file = LICENSE license_file = LICENSE
@ -13,6 +13,11 @@ classifiers =
Operating System :: OS Independent Operating System :: OS Independent
Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 :: Only
[project.urls]
homepage = https://customtkinter.tomschimansky.com
documentation = https://customtkinter.tomschimansky.com/documentation
repository = https://github.com/tomschimansky/customtkinter
[options] [options]
python_requires = >=3.7 python_requires = >=3.7
packages = packages =

View File

@ -1,5 +1,7 @@
import customtkinter import customtkinter
customtkinter.set_default_color_theme("dark-blue")
app = customtkinter.CTk() app = customtkinter.CTk()
app.grid_columnconfigure(2, weight=1) app.grid_columnconfigure(2, weight=1)
@ -26,7 +28,7 @@ frame_4.configure(label_text="CTkScrollableFrame")
frame_5 = customtkinter.CTkScrollableFrame(app, orientation="vertical", label_text="CTkScrollableFrame", corner_radius=0) frame_5 = customtkinter.CTkScrollableFrame(app, orientation="vertical", label_text="CTkScrollableFrame", corner_radius=0)
frame_5.grid(row=0, column=2, rowspan=2, sticky="nsew") frame_5.grid(row=0, column=2, rowspan=2, sticky="nsew")
for i in range(20): for i in range(100):
customtkinter.CTkCheckBox(frame_1).grid(row=i, padx=10, pady=10) customtkinter.CTkCheckBox(frame_1).grid(row=i, padx=10, pady=10)
customtkinter.CTkCheckBox(frame_2).grid(row=i, padx=10, pady=10) customtkinter.CTkCheckBox(frame_2).grid(row=i, padx=10, pady=10)
customtkinter.CTkCheckBox(frame_3).grid(row=0, column=i, padx=10, pady=10) customtkinter.CTkCheckBox(frame_3).grid(row=0, column=i, padx=10, pady=10)