mirror of
https://github.com/TomSchimansky/CustomTkinter.git
synced 2023-08-10 21:13:13 +03:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
f49c83d2dc | |||
4389c3e86b | |||
25297c2598 | |||
4e155aedd6 | |||
3a5d34cef6 | |||
e42db49ca5 | |||
a7c0fc2a3c | |||
9be2a76b25 | |||
b1ac3b6d45 | |||
a6b563abb1 |
@ -1,4 +1,4 @@
|
|||||||
__version__ = "4.0.2"
|
__version__ = "4.1.0"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -51,7 +51,7 @@ class FontManager:
|
|||||||
return cls.windows_load_font(font_path, private=True, enumerable=False)
|
return cls.windows_load_font(font_path, private=True, enumerable=False)
|
||||||
|
|
||||||
# Linux
|
# Linux
|
||||||
elif sys.platform.startswith("win"):
|
elif sys.platform.startswith("linux"):
|
||||||
try:
|
try:
|
||||||
shutil.copy(font_path, os.path.expanduser("~/.fonts/"))
|
shutil.copy(font_path, os.path.expanduser("~/.fonts/"))
|
||||||
return True
|
return True
|
||||||
|
@ -99,7 +99,14 @@ class CTkButton(CTkBaseClass):
|
|||||||
self.image_label = None
|
self.image_label = None
|
||||||
|
|
||||||
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
|
||||||
height=self.apply_widget_scaling(self.desired_height)),
|
height=self.apply_widget_scaling(self.desired_height))
|
||||||
|
self.draw()
|
||||||
|
|
||||||
|
def set_dimensions(self, width=None, height=None):
|
||||||
|
super().set_dimensions(width, height)
|
||||||
|
|
||||||
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
|
||||||
|
height=self.apply_widget_scaling(self.desired_height))
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def draw(self, no_color_updates=False):
|
def draw(self, no_color_updates=False):
|
||||||
@ -290,6 +297,14 @@ class CTkButton(CTkBaseClass):
|
|||||||
self.text_label.configure(textvariable=self.textvariable)
|
self.text_label.configure(textvariable=self.textvariable)
|
||||||
del kwargs["textvariable"]
|
del kwargs["textvariable"]
|
||||||
|
|
||||||
|
if "width" in kwargs:
|
||||||
|
self.set_dimensions(width=kwargs["width"])
|
||||||
|
del kwargs["width"]
|
||||||
|
|
||||||
|
if "height" in kwargs:
|
||||||
|
self.set_dimensions(height=kwargs["height"])
|
||||||
|
del kwargs["height"]
|
||||||
|
|
||||||
super().configure(*args, **kwargs)
|
super().configure(*args, **kwargs)
|
||||||
|
|
||||||
if require_redraw:
|
if require_redraw:
|
||||||
|
@ -81,6 +81,13 @@ class CTkEntry(CTkBaseClass):
|
|||||||
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width), height=self.apply_widget_scaling(self.desired_height))
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width), height=self.apply_widget_scaling(self.desired_height))
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
|
def set_dimensions(self, width=None, height=None):
|
||||||
|
super().set_dimensions(width, height)
|
||||||
|
|
||||||
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
|
||||||
|
height=self.apply_widget_scaling(self.desired_height))
|
||||||
|
self.draw()
|
||||||
|
|
||||||
def set_placeholder(self, event=None):
|
def set_placeholder(self, event=None):
|
||||||
if self.placeholder_text is not None:
|
if self.placeholder_text is not None:
|
||||||
if not self.placeholder_text_active and self.entry.get() == "":
|
if not self.placeholder_text_active and self.entry.get() == "":
|
||||||
@ -181,6 +188,14 @@ class CTkEntry(CTkBaseClass):
|
|||||||
del kwargs["corner_radius"]
|
del kwargs["corner_radius"]
|
||||||
require_redraw = True
|
require_redraw = True
|
||||||
|
|
||||||
|
if "width" in kwargs:
|
||||||
|
self.set_dimensions(width=kwargs["width"])
|
||||||
|
del kwargs["width"]
|
||||||
|
|
||||||
|
if "height" in kwargs:
|
||||||
|
self.set_dimensions(height=kwargs["height"])
|
||||||
|
del kwargs["height"]
|
||||||
|
|
||||||
if "placeholder_text" in kwargs:
|
if "placeholder_text" in kwargs:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import tkinter
|
|
||||||
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..theme_manager import ThemeManager
|
from ..theme_manager import ThemeManager
|
||||||
from ..settings import Settings
|
|
||||||
from ..draw_engine import DrawEngine
|
from ..draw_engine import DrawEngine
|
||||||
from .widget_base_class import CTkBaseClass
|
from .widget_base_class import CTkBaseClass
|
||||||
|
|
||||||
@ -68,6 +65,13 @@ class CTkFrame(CTkBaseClass):
|
|||||||
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width), height=self.apply_widget_scaling(self.desired_height))
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width), height=self.apply_widget_scaling(self.desired_height))
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
|
def set_dimensions(self, width=None, height=None):
|
||||||
|
super().set_dimensions(width, height)
|
||||||
|
|
||||||
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
|
||||||
|
height=self.apply_widget_scaling(self.desired_height))
|
||||||
|
self.draw()
|
||||||
|
|
||||||
def draw(self, no_color_updates=False):
|
def draw(self, no_color_updates=False):
|
||||||
|
|
||||||
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.apply_widget_scaling(self.current_width),
|
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.apply_widget_scaling(self.current_width),
|
||||||
@ -130,6 +134,14 @@ class CTkFrame(CTkBaseClass):
|
|||||||
require_redraw = True
|
require_redraw = True
|
||||||
del kwargs["border_width"]
|
del kwargs["border_width"]
|
||||||
|
|
||||||
|
if "width" in kwargs:
|
||||||
|
self.set_dimensions(width=kwargs["width"])
|
||||||
|
del kwargs["width"]
|
||||||
|
|
||||||
|
if "height" in kwargs:
|
||||||
|
self.set_dimensions(height=kwargs["height"])
|
||||||
|
del kwargs["height"]
|
||||||
|
|
||||||
super().configure(*args, **kwargs)
|
super().configure(*args, **kwargs)
|
||||||
|
|
||||||
if require_redraw:
|
if require_redraw:
|
||||||
|
@ -69,6 +69,13 @@ class CTkLabel(CTkBaseClass):
|
|||||||
|
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
|
def set_dimensions(self, width=None, height=None):
|
||||||
|
super().set_dimensions(width, height)
|
||||||
|
|
||||||
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
|
||||||
|
height=self.apply_widget_scaling(self.desired_height))
|
||||||
|
self.draw()
|
||||||
|
|
||||||
def draw(self, no_color_updates=False):
|
def draw(self, no_color_updates=False):
|
||||||
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.apply_widget_scaling(self.current_width),
|
requires_recoloring = self.draw_engine.draw_rounded_rect_with_border(self.apply_widget_scaling(self.current_width),
|
||||||
self.apply_widget_scaling(self.current_height),
|
self.apply_widget_scaling(self.current_height),
|
||||||
@ -118,6 +125,14 @@ class CTkLabel(CTkBaseClass):
|
|||||||
require_redraw = True
|
require_redraw = True
|
||||||
del kwargs["text_color"]
|
del kwargs["text_color"]
|
||||||
|
|
||||||
|
if "width" in kwargs:
|
||||||
|
self.set_dimensions(width=kwargs["width"])
|
||||||
|
del kwargs["width"]
|
||||||
|
|
||||||
|
if "height" in kwargs:
|
||||||
|
self.set_dimensions(height=kwargs["height"])
|
||||||
|
del kwargs["height"]
|
||||||
|
|
||||||
self.text_label.configure(*args, **kwargs)
|
self.text_label.configure(*args, **kwargs)
|
||||||
|
|
||||||
if require_redraw:
|
if require_redraw:
|
||||||
|
@ -81,6 +81,13 @@ class CTkProgressBar(CTkBaseClass):
|
|||||||
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width), height=self.apply_widget_scaling(self.desired_height))
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width), height=self.apply_widget_scaling(self.desired_height))
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
|
def set_dimensions(self, width=None, height=None):
|
||||||
|
super().set_dimensions(width, height)
|
||||||
|
|
||||||
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
|
||||||
|
height=self.apply_widget_scaling(self.desired_height))
|
||||||
|
self.draw()
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
if self.variable is not None:
|
if self.variable is not None:
|
||||||
self.variable.trace_remove("write", self.variable_callback_name)
|
self.variable.trace_remove("write", self.variable_callback_name)
|
||||||
@ -159,6 +166,14 @@ class CTkProgressBar(CTkBaseClass):
|
|||||||
|
|
||||||
del kwargs["variable"]
|
del kwargs["variable"]
|
||||||
|
|
||||||
|
if "width" in kwargs:
|
||||||
|
self.set_dimensions(width=kwargs["width"])
|
||||||
|
del kwargs["width"]
|
||||||
|
|
||||||
|
if "height" in kwargs:
|
||||||
|
self.set_dimensions(height=kwargs["height"])
|
||||||
|
del kwargs["height"]
|
||||||
|
|
||||||
super().configure(*args, **kwargs)
|
super().configure(*args, **kwargs)
|
||||||
|
|
||||||
if require_redraw is True:
|
if require_redraw is True:
|
||||||
|
@ -109,6 +109,13 @@ class CTkSlider(CTkBaseClass):
|
|||||||
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width), height=self.apply_widget_scaling(self.desired_height))
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width), height=self.apply_widget_scaling(self.desired_height))
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
|
def set_dimensions(self, width=None, height=None):
|
||||||
|
super().set_dimensions(width, height)
|
||||||
|
|
||||||
|
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
|
||||||
|
height=self.apply_widget_scaling(self.desired_height))
|
||||||
|
self.draw()
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
# remove variable_callback from variable callbacks if variable exists
|
# remove variable_callback from variable callbacks if variable exists
|
||||||
if self.variable is not None:
|
if self.variable is not None:
|
||||||
@ -310,6 +317,14 @@ class CTkSlider(CTkBaseClass):
|
|||||||
|
|
||||||
del kwargs["variable"]
|
del kwargs["variable"]
|
||||||
|
|
||||||
|
if "width" in kwargs:
|
||||||
|
self.set_dimensions(width=kwargs["width"])
|
||||||
|
del kwargs["width"]
|
||||||
|
|
||||||
|
if "height" in kwargs:
|
||||||
|
self.set_dimensions(height=kwargs["height"])
|
||||||
|
del kwargs["height"]
|
||||||
|
|
||||||
super().configure(*args, **kwargs)
|
super().configure(*args, **kwargs)
|
||||||
|
|
||||||
if require_redraw:
|
if require_redraw:
|
||||||
|
@ -2,7 +2,12 @@ import tkinter
|
|||||||
import tkinter.ttk as ttk
|
import tkinter.ttk as ttk
|
||||||
import copy
|
import copy
|
||||||
import re
|
import re
|
||||||
from typing import Callable, Union, TypedDict
|
from typing import Callable, Union
|
||||||
|
|
||||||
|
try:
|
||||||
|
from typing import TypedDict
|
||||||
|
except ImportError:
|
||||||
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
from ..windows.ctk_tk import CTk
|
from ..windows.ctk_tk import CTk
|
||||||
from ..windows.ctk_toplevel import CTkToplevel
|
from ..windows.ctk_toplevel import CTkToplevel
|
||||||
@ -130,22 +135,30 @@ class CTkBaseClass(tkinter.Frame):
|
|||||||
|
|
||||||
self.draw(no_color_updates=True) # faster drawing without color changes
|
self.draw(no_color_updates=True) # faster drawing without color changes
|
||||||
|
|
||||||
def detect_color_of_master(self):
|
def detect_color_of_master(self, master_widget=None):
|
||||||
""" detect color of self.master widget to set correct bg_color """
|
""" detect color of self.master widget to set correct bg_color """
|
||||||
|
|
||||||
if isinstance(self.master, CTkBaseClass) and hasattr(self.master, "fg_color"): # master is CTkFrame
|
if master_widget is None:
|
||||||
return self.master.fg_color
|
master_widget = self.master
|
||||||
|
|
||||||
elif isinstance(self.master, (ttk.Frame, ttk.LabelFrame, ttk.Notebook)): # master is ttk widget
|
if isinstance(master_widget, CTkBaseClass) and hasattr(master_widget, "fg_color"): # master is CTkFrame
|
||||||
|
if master_widget.fg_color is not None:
|
||||||
|
return master_widget.fg_color
|
||||||
|
|
||||||
|
# if fg_color of master is None, try to retrieve fg_color from master of master
|
||||||
|
elif hasattr(master_widget.master, "master"):
|
||||||
|
return self.detect_color_of_master(self.master.master)
|
||||||
|
|
||||||
|
elif isinstance(master_widget, (ttk.Frame, ttk.LabelFrame, ttk.Notebook)): # master is ttk widget
|
||||||
try:
|
try:
|
||||||
ttk_style = ttk.Style()
|
ttk_style = ttk.Style()
|
||||||
return ttk_style.lookup(self.master.winfo_class(), 'background')
|
return ttk_style.lookup(master_widget.winfo_class(), 'background')
|
||||||
except Exception:
|
except Exception:
|
||||||
return "#FFFFFF", "#000000"
|
return "#FFFFFF", "#000000"
|
||||||
|
|
||||||
else: # master is normal tkinter widget
|
else: # master is normal tkinter widget
|
||||||
try:
|
try:
|
||||||
return self.master.cget("bg") # try to get bg color by .cget() method
|
return master_widget.cget("bg") # try to get bg color by .cget() method
|
||||||
except Exception:
|
except Exception:
|
||||||
return "#FFFFFF", "#000000"
|
return "#FFFFFF", "#000000"
|
||||||
|
|
||||||
@ -172,6 +185,15 @@ class CTkBaseClass(tkinter.Frame):
|
|||||||
if self.last_geometry_manager_call is not None:
|
if self.last_geometry_manager_call is not None:
|
||||||
self.last_geometry_manager_call["function"](**self.apply_argument_scaling(self.last_geometry_manager_call["kwargs"]))
|
self.last_geometry_manager_call["function"](**self.apply_argument_scaling(self.last_geometry_manager_call["kwargs"]))
|
||||||
|
|
||||||
|
def set_dimensions(self, width=None, height=None):
|
||||||
|
if width is not None:
|
||||||
|
self.desired_width = width
|
||||||
|
if height is not None:
|
||||||
|
self.desired_height = height
|
||||||
|
|
||||||
|
super().configure(width=self.apply_widget_scaling(self.desired_width),
|
||||||
|
height=self.apply_widget_scaling(self.desired_height))
|
||||||
|
|
||||||
def apply_widget_scaling(self, value):
|
def apply_widget_scaling(self, value):
|
||||||
if isinstance(value, (int, float)):
|
if isinstance(value, (int, float)):
|
||||||
return value * self.widget_scaling
|
return value * self.widget_scaling
|
||||||
|
@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
github_url = "https://github.com/TomSchimansky/CustomTkinter"
|
github_url = "https://github.com/TomSchimansky/CustomTkinter"
|
||||||
|
|
||||||
[tool.tbump.version]
|
[tool.tbump.version]
|
||||||
current = "4.0.2"
|
current = "4.1.0"
|
||||||
|
|
||||||
# Example of a semver regexp.
|
# Example of a semver regexp.
|
||||||
# Make sure this matches current_version before
|
# Make sure this matches current_version before
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[metadata]
|
[metadata]
|
||||||
name = customtkinter
|
name = customtkinter
|
||||||
version = 4.0.2
|
version = 4.1.0
|
||||||
description = Create modern looking GUIs with Python
|
description = Create modern looking GUIs with Python
|
||||||
long_description = file: README.md
|
long_description = file: README.md
|
||||||
long_description_content_type = text/markdown
|
long_description_content_type = text/markdown
|
||||||
@ -14,10 +14,12 @@ classifiers =
|
|||||||
Programming Language :: Python :: 3 :: Only
|
Programming Language :: Python :: 3 :: Only
|
||||||
|
|
||||||
[options]
|
[options]
|
||||||
|
python_requires = >=3.7
|
||||||
packages =
|
packages =
|
||||||
customtkinter
|
customtkinter
|
||||||
customtkinter.widgets
|
customtkinter.widgets
|
||||||
customtkinter.windows
|
customtkinter.windows
|
||||||
install_requires =
|
install_requires =
|
||||||
darkdetect
|
darkdetect
|
||||||
|
typing_extensions; python_version<="3.7"
|
||||||
include_package_data = True
|
include_package_data = True
|
||||||
|
36
test/manual_integration_tests/test_configure_dimensions.py
Normal file
36
test/manual_integration_tests/test_configure_dimensions.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import customtkinter
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
app = customtkinter.CTk()
|
||||||
|
app.geometry("400x400")
|
||||||
|
|
||||||
|
|
||||||
|
def button_callback():
|
||||||
|
button_1.configure(width=random.randint(30, 200), height=random.randint(30, 60))
|
||||||
|
frame_1.configure(width=random.randint(30, 200), height=random.randint(30, 200))
|
||||||
|
label_1.configure(width=random.randint(30, 200), height=random.randint(30, 40))
|
||||||
|
entry_1.configure(width=random.randint(30, 200), height=random.randint(30, 40))
|
||||||
|
progressbar_1.configure(width=random.randint(30, 200), height=random.randint(10, 16))
|
||||||
|
slider_1.configure(width=random.randint(30, 200), height=random.randint(14, 20))
|
||||||
|
|
||||||
|
|
||||||
|
button_1 = customtkinter.CTkButton(app, text="button_1", command=button_callback)
|
||||||
|
button_1.pack(pady=10)
|
||||||
|
|
||||||
|
frame_1 = customtkinter.CTkFrame(app)
|
||||||
|
frame_1.pack(pady=10)
|
||||||
|
|
||||||
|
label_1 = customtkinter.CTkLabel(app, fg_color="green")
|
||||||
|
label_1.pack(pady=10)
|
||||||
|
|
||||||
|
entry_1 = customtkinter.CTkEntry(app, placeholder_text="placeholder")
|
||||||
|
entry_1.pack(pady=10)
|
||||||
|
|
||||||
|
progressbar_1 = customtkinter.CTkProgressBar(app)
|
||||||
|
progressbar_1.pack(pady=10)
|
||||||
|
|
||||||
|
slider_1 = customtkinter.CTkSlider(app)
|
||||||
|
slider_1.pack(pady=10)
|
||||||
|
|
||||||
|
app.mainloop()
|
Reference in New Issue
Block a user