mirror of
https://github.com/TomSchimansky/CustomTkinter.git
synced 2023-08-10 21:13:13 +03:00
fixed scrollbar for horizontal orientation
This commit is contained in:
parent
a7b175ae65
commit
ec3fdc40ff
@ -1,7 +1,5 @@
|
|||||||
import sys
|
import sys
|
||||||
import tkinter
|
|
||||||
|
|
||||||
from .ctk_frame import CTkFrame
|
|
||||||
from .ctk_canvas import CTkCanvas
|
from .ctk_canvas import CTkCanvas
|
||||||
from ..theme_manager import ThemeManager
|
from ..theme_manager import ThemeManager
|
||||||
from ..draw_engine import DrawEngine
|
from ..draw_engine import DrawEngine
|
||||||
@ -18,6 +16,7 @@ class CTkScrollbar(CTkBaseClass):
|
|||||||
corner_radius="default_theme",
|
corner_radius="default_theme",
|
||||||
width=None,
|
width=None,
|
||||||
height=None,
|
height=None,
|
||||||
|
minimum_pixel_length=20,
|
||||||
orientation="vertical",
|
orientation="vertical",
|
||||||
command=None,
|
command=None,
|
||||||
hover=True,
|
hover=True,
|
||||||
@ -30,10 +29,10 @@ class CTkScrollbar(CTkBaseClass):
|
|||||||
else:
|
else:
|
||||||
width = 200
|
width = 200
|
||||||
if height is None:
|
if height is None:
|
||||||
if orientation.lower() == "vertical":
|
if orientation.lower() == "horizontal":
|
||||||
height = 200
|
|
||||||
else:
|
|
||||||
height = 16
|
height = 16
|
||||||
|
else:
|
||||||
|
height = 200
|
||||||
|
|
||||||
# transfer basic functionality (bg_color, size, _appearance_mode, scaling) to CTkBaseClass
|
# transfer basic functionality (bg_color, size, _appearance_mode, scaling) to CTkBaseClass
|
||||||
super().__init__(*args, bg_color=bg_color, width=width, height=height, **kwargs)
|
super().__init__(*args, bg_color=bg_color, width=width, height=height, **kwargs)
|
||||||
@ -53,6 +52,7 @@ class CTkScrollbar(CTkBaseClass):
|
|||||||
self.orientation = orientation
|
self.orientation = orientation
|
||||||
self.start_value: float = 0 # 0 to 1
|
self.start_value: float = 0 # 0 to 1
|
||||||
self.end_value: float = 1 # 0 to 1
|
self.end_value: float = 1 # 0 to 1
|
||||||
|
self.minimum_pixel_length = minimum_pixel_length
|
||||||
|
|
||||||
self.canvas = CTkCanvas(master=self,
|
self.canvas = CTkCanvas(master=self,
|
||||||
highlightthickness=0,
|
highlightthickness=0,
|
||||||
@ -83,12 +83,38 @@ class CTkScrollbar(CTkBaseClass):
|
|||||||
height=self.apply_widget_scaling(self._desired_height))
|
height=self.apply_widget_scaling(self._desired_height))
|
||||||
self.draw(no_color_updates=True)
|
self.draw(no_color_updates=True)
|
||||||
|
|
||||||
|
def get_scrollbar_values_for_minimum_pixel_size(self):
|
||||||
|
# correct scrollbar float values if scrollbar is too small
|
||||||
|
if self.orientation == "vertical":
|
||||||
|
scrollbar_pixel_length = (self.end_value - self.start_value) * self._current_height
|
||||||
|
if scrollbar_pixel_length < self.minimum_pixel_length and -scrollbar_pixel_length + self._current_height != 0:
|
||||||
|
# calculate how much to increase the float interval values so that the scrollbar width is self.minimum_pixel_length
|
||||||
|
interval_extend_factor = (-scrollbar_pixel_length + self.minimum_pixel_length) / (-scrollbar_pixel_length + self._current_height)
|
||||||
|
corrected_end_value = self.end_value + (1 - self.end_value) * interval_extend_factor
|
||||||
|
corrected_start_value = self.start_value - self.start_value * interval_extend_factor
|
||||||
|
return corrected_start_value, corrected_end_value
|
||||||
|
else:
|
||||||
|
return self.start_value, self.end_value
|
||||||
|
|
||||||
|
else:
|
||||||
|
scrollbar_pixel_length = (self.end_value - self.start_value) * self._current_width
|
||||||
|
if scrollbar_pixel_length < self.minimum_pixel_length and -scrollbar_pixel_length + self._current_width != 0:
|
||||||
|
# calculate how much to increase the float interval values so that the scrollbar width is self.minimum_pixel_length
|
||||||
|
interval_extend_factor = (-scrollbar_pixel_length + self.minimum_pixel_length) / (-scrollbar_pixel_length + self._current_width)
|
||||||
|
corrected_end_value = self.end_value + (1 - self.end_value) * interval_extend_factor
|
||||||
|
corrected_start_value = self.start_value - self.start_value * interval_extend_factor
|
||||||
|
return corrected_start_value, corrected_end_value
|
||||||
|
else:
|
||||||
|
return self.start_value, self.end_value
|
||||||
|
|
||||||
def draw(self, no_color_updates=False):
|
def draw(self, no_color_updates=False):
|
||||||
|
corrected_start_value, corrected_end_value = self.get_scrollbar_values_for_minimum_pixel_size()
|
||||||
requires_recoloring = self.draw_engine.draw_rounded_scrollbar(self.apply_widget_scaling(self._current_width),
|
requires_recoloring = self.draw_engine.draw_rounded_scrollbar(self.apply_widget_scaling(self._current_width),
|
||||||
self.apply_widget_scaling(self._current_height),
|
self.apply_widget_scaling(self._current_height),
|
||||||
self.apply_widget_scaling(self.corner_radius),
|
self.apply_widget_scaling(self.corner_radius),
|
||||||
self.apply_widget_scaling(self.border_spacing),
|
self.apply_widget_scaling(self.border_spacing),
|
||||||
self.start_value, self.end_value,
|
corrected_start_value,
|
||||||
|
corrected_end_value,
|
||||||
self.orientation)
|
self.orientation)
|
||||||
|
|
||||||
if no_color_updates is False or requires_recoloring:
|
if no_color_updates is False or requires_recoloring:
|
||||||
@ -102,10 +128,12 @@ class CTkScrollbar(CTkBaseClass):
|
|||||||
outline=ThemeManager.single_color(self.scrollbar_color, self._appearance_mode))
|
outline=ThemeManager.single_color(self.scrollbar_color, self._appearance_mode))
|
||||||
|
|
||||||
if self.fg_color is None:
|
if self.fg_color is None:
|
||||||
|
self.canvas.configure(bg=ThemeManager.single_color(self.bg_color, self._appearance_mode))
|
||||||
self.canvas.itemconfig("border_parts",
|
self.canvas.itemconfig("border_parts",
|
||||||
fill=ThemeManager.single_color(self.bg_color, self._appearance_mode),
|
fill=ThemeManager.single_color(self.bg_color, self._appearance_mode),
|
||||||
outline=ThemeManager.single_color(self.bg_color, self._appearance_mode))
|
outline=ThemeManager.single_color(self.bg_color, self._appearance_mode))
|
||||||
else:
|
else:
|
||||||
|
self.canvas.configure(bg=ThemeManager.single_color(self.fg_color, self._appearance_mode))
|
||||||
self.canvas.itemconfig("border_parts",
|
self.canvas.itemconfig("border_parts",
|
||||||
fill=ThemeManager.single_color(self.fg_color, self._appearance_mode),
|
fill=ThemeManager.single_color(self.fg_color, self._appearance_mode),
|
||||||
outline=ThemeManager.single_color(self.fg_color, self._appearance_mode))
|
outline=ThemeManager.single_color(self.fg_color, self._appearance_mode))
|
||||||
@ -115,7 +143,6 @@ class CTkScrollbar(CTkBaseClass):
|
|||||||
def set(self, start_value: float, end_value: float):
|
def set(self, start_value: float, end_value: float):
|
||||||
self.start_value = float(start_value)
|
self.start_value = float(start_value)
|
||||||
self.end_value = float(end_value)
|
self.end_value = float(end_value)
|
||||||
self.scrollbar_height = self.end_value - self.start_value
|
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
@ -190,6 +217,9 @@ class CTkScrollbar(CTkBaseClass):
|
|||||||
def clicked(self, event):
|
def clicked(self, event):
|
||||||
if self.orientation == "vertical":
|
if self.orientation == "vertical":
|
||||||
value = ((event.y - self.border_spacing) / (self._current_height - 2 * self.border_spacing)) / self._widget_scaling
|
value = ((event.y - self.border_spacing) / (self._current_height - 2 * self.border_spacing)) / self._widget_scaling
|
||||||
|
else:
|
||||||
|
value = ((event.x - self.border_spacing) / (self._current_width - 2 * self.border_spacing)) / self._widget_scaling
|
||||||
|
|
||||||
current_scrollbar_length = self.end_value - self.start_value
|
current_scrollbar_length = self.end_value - self.start_value
|
||||||
value = max(current_scrollbar_length / 2, min(value, 1 - (current_scrollbar_length / 2)))
|
value = max(current_scrollbar_length / 2, min(value, 1 - (current_scrollbar_length / 2)))
|
||||||
self.start_value = value - (current_scrollbar_length / 2)
|
self.start_value = value - (current_scrollbar_length / 2)
|
||||||
|
@ -12,7 +12,7 @@ def select_callback(choice):
|
|||||||
print("display_selected", choice)
|
print("display_selected", choice)
|
||||||
|
|
||||||
|
|
||||||
countries = ['Bahamas', 'Canada', 'Cuba', 'United States']
|
countries = ['Bahamas', 'Canada', 'Cuba', 'United States', "long sdhfhjgdshjafghdgshfhjdsfj"]
|
||||||
|
|
||||||
variable = tkinter.StringVar()
|
variable = tkinter.StringVar()
|
||||||
variable.set("test")
|
variable.set("test")
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import tkinter
|
import tkinter
|
||||||
import customtkinter
|
import customtkinter
|
||||||
|
|
||||||
# customtkinter.DrawEngine.preferred_drawing_method = "font_shapes"
|
# test with scaling
|
||||||
#customtkinter.set_widget_scaling(2)
|
# customtkinter.set_widget_scaling(2)
|
||||||
#customtkinter.set_window_scaling(2)
|
# customtkinter.set_window_scaling(2)
|
||||||
#customtkinter.set_spacing_scaling(2)
|
# customtkinter.set_spacing_scaling(2)
|
||||||
|
|
||||||
customtkinter.set_appearance_mode("light")
|
customtkinter.set_appearance_mode("dark")
|
||||||
|
|
||||||
app = customtkinter.CTk()
|
app = customtkinter.CTk()
|
||||||
|
app.title("test_scrollbar.py")
|
||||||
app.grid_rowconfigure(0, weight=1)
|
app.grid_rowconfigure(0, weight=1)
|
||||||
app.grid_columnconfigure((0, 2), weight=1)
|
app.grid_columnconfigure((0, 2), weight=1)
|
||||||
|
|
||||||
@ -27,16 +28,20 @@ tk_textbox_1.grid(row=0, column=0, sticky="nsew", padx=(5, 0), pady=5)
|
|||||||
ctk_textbox_scrollbar_1 = customtkinter.CTkScrollbar(frame_1, command=tk_textbox_1.yview)
|
ctk_textbox_scrollbar_1 = customtkinter.CTkScrollbar(frame_1, command=tk_textbox_1.yview)
|
||||||
ctk_textbox_scrollbar_1.grid(row=0, column=1, sticky="ns", padx=(0, 5), pady=5)
|
ctk_textbox_scrollbar_1.grid(row=0, column=1, sticky="ns", padx=(0, 5), pady=5)
|
||||||
tk_textbox_1.configure(yscrollcommand=ctk_textbox_scrollbar_1.set)
|
tk_textbox_1.configure(yscrollcommand=ctk_textbox_scrollbar_1.set)
|
||||||
|
ctk_textbox_scrollbar_1.configure(scrollbar_color="red", scrollbar_hover_color="darkred",
|
||||||
|
border_spacing=0, width=12, fg_color="green", corner_radius=4)
|
||||||
|
|
||||||
frame_2 = customtkinter.CTkFrame(frame_1)
|
frame_2 = customtkinter.CTkFrame(frame_1)
|
||||||
frame_2.grid(row=1, column=0, columnspan=2, padx=20, pady=20, sticky="nsew")
|
frame_2.grid(row=1, column=0, columnspan=2, padx=20, pady=20, sticky="nsew")
|
||||||
frame_2.grid_rowconfigure((0, 1), weight=1)
|
frame_2.grid_rowconfigure((0, 1), weight=1)
|
||||||
frame_2.grid_columnconfigure((0, ), weight=1)
|
frame_2.grid_columnconfigure((0, ), weight=1)
|
||||||
tk_textbox_2 = tkinter.Text(frame_2, highlightthickness=0, padx=5, pady=5)
|
tk_textbox_2 = tkinter.Text(frame_2, highlightthickness=0, padx=5, pady=5, wrap="none")
|
||||||
tk_textbox_2.grid(row=0, column=0, sticky="nsew", padx=(5, 0), pady=5)
|
tk_textbox_2.grid(row=0, column=0, sticky="nsew", padx=(5, 0), pady=5)
|
||||||
ctk_textbox_scrollbar_2 = customtkinter.CTkScrollbar(frame_2, command=tk_textbox_2.yview)
|
ctk_textbox_scrollbar_2 = customtkinter.CTkScrollbar(frame_2, command=tk_textbox_2.yview)
|
||||||
ctk_textbox_scrollbar_2.grid(row=0, column=1, sticky="ns", padx=(0, 5), pady=5)
|
ctk_textbox_scrollbar_2.grid(row=0, column=1, sticky="ns", padx=(0, 5), pady=5)
|
||||||
tk_textbox_2.configure(yscrollcommand=ctk_textbox_scrollbar_2.set)
|
ctk_textbox_scrollbar_2_horizontal = customtkinter.CTkScrollbar(frame_2, command=tk_textbox_2.xview, orientation="horizontal")
|
||||||
|
ctk_textbox_scrollbar_2_horizontal.grid(row=1, column=0, sticky="ew", padx=(5, 0), pady=(0, 5))
|
||||||
|
tk_textbox_2.configure(yscrollcommand=ctk_textbox_scrollbar_2.set, xscrollcommand=ctk_textbox_scrollbar_2_horizontal.set)
|
||||||
|
|
||||||
tk_textbox.configure(font=(customtkinter.ThemeManager.theme["text"]["font"], customtkinter.ThemeManager.theme["text"]["size"]))
|
tk_textbox.configure(font=(customtkinter.ThemeManager.theme["text"]["font"], customtkinter.ThemeManager.theme["text"]["size"]))
|
||||||
tk_textbox_1.configure(font=(customtkinter.ThemeManager.theme["text"]["font"], customtkinter.ThemeManager.theme["text"]["size"]))
|
tk_textbox_1.configure(font=(customtkinter.ThemeManager.theme["text"]["font"], customtkinter.ThemeManager.theme["text"]["size"]))
|
||||||
@ -44,6 +49,6 @@ tk_textbox_2.configure(font=(customtkinter.ThemeManager.theme["text"]["font"], c
|
|||||||
|
|
||||||
tk_textbox.insert("insert", "\n".join([str(i) for i in range(100)]))
|
tk_textbox.insert("insert", "\n".join([str(i) for i in range(100)]))
|
||||||
tk_textbox_1.insert("insert", "\n".join([str(i) for i in range(1000)]))
|
tk_textbox_1.insert("insert", "\n".join([str(i) for i in range(1000)]))
|
||||||
tk_textbox_2.insert("insert", "\n".join([str(i) for i in range(10000)]))
|
tk_textbox_2.insert("insert", "\n".join([str(i) + " - "*30 for i in range(10000)]))
|
||||||
|
|
||||||
app.mainloop()
|
app.mainloop()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user