mirror of
https://github.com/TomSchimansky/CustomTkinter.git
synced 2023-08-10 21:13:13 +03:00
138 lines
5.8 KiB
Python
138 lines
5.8 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any, Callable
|
|
|
|
import customtkinter
|
|
import os
|
|
from PIL import Image
|
|
|
|
|
|
class ScrollableCheckBoxFrame(customtkinter.CTkScrollableFrame):
|
|
def __init__(self, master, item_list: list[str], command: Callable[..., None] | None = None, **kwargs: Any):
|
|
super().__init__(master, **kwargs)
|
|
|
|
self.command = command
|
|
self.checkbox_list: list[customtkinter.CTkCheckBox] = []
|
|
for item in item_list:
|
|
self.add_item(item)
|
|
|
|
def add_item(self, item: str):
|
|
checkbox = customtkinter.CTkCheckBox(self, text=item)
|
|
if self.command is not None:
|
|
checkbox.configure(command=self.command)
|
|
checkbox.grid(row=len(self.checkbox_list), column=0, pady=(0, 10))
|
|
self.checkbox_list.append(checkbox)
|
|
|
|
def remove_item(self, item: str):
|
|
for checkbox in self.checkbox_list:
|
|
if item == checkbox.cget("text"):
|
|
checkbox.destroy()
|
|
self.checkbox_list.remove(checkbox)
|
|
return
|
|
|
|
def get_checked_items(self):
|
|
return [checkbox.cget("text") for checkbox in self.checkbox_list if checkbox.get() == 1]
|
|
|
|
|
|
class ScrollableRadiobuttonFrame(customtkinter.CTkScrollableFrame):
|
|
def __init__(self, master, item_list: list[str], command: Callable[..., None] | None = None, **kwargs: Any):
|
|
super().__init__(master, **kwargs)
|
|
|
|
self.command = command
|
|
self.radiobutton_variable = customtkinter.StringVar()
|
|
self.radiobutton_list = []
|
|
for i, item in enumerate(item_list):
|
|
self.add_item(item)
|
|
|
|
def add_item(self, item):
|
|
radiobutton = customtkinter.CTkRadioButton(self, text=item, value=item, variable=self.radiobutton_variable)
|
|
if self.command is not None:
|
|
radiobutton.configure(command=self.command)
|
|
radiobutton.grid(row=len(self.radiobutton_list), column=0, pady=(0, 10))
|
|
self.radiobutton_list.append(radiobutton)
|
|
|
|
def remove_item(self, item):
|
|
for radiobutton in self.radiobutton_list:
|
|
if item == radiobutton.cget("text"):
|
|
radiobutton.destroy()
|
|
self.radiobutton_list.remove(radiobutton)
|
|
return
|
|
|
|
def get_checked_item(self):
|
|
return self.radiobutton_variable.get()
|
|
|
|
|
|
class ScrollableLabelButtonFrame(customtkinter.CTkScrollableFrame):
|
|
def __init__(self, master, command=None, **kwargs: Any):
|
|
super().__init__(master, **kwargs)
|
|
self.grid_columnconfigure(0, weight=1)
|
|
|
|
self.command = command
|
|
self.radiobutton_variable = customtkinter.StringVar()
|
|
self.label_list = []
|
|
self.button_list = []
|
|
|
|
def add_item(self, item, image=None):
|
|
label = customtkinter.CTkLabel(self, text=item, image=image, compound="left", padx=5, anchor="w")
|
|
button = customtkinter.CTkButton(self, text="Command", width=100, height=24)
|
|
if self.command is not None:
|
|
button.configure(command=lambda: self.command(item))
|
|
label.grid(row=len(self.label_list), column=0, pady=(0, 10), sticky="w")
|
|
button.grid(row=len(self.button_list), column=1, pady=(0, 10), padx=5)
|
|
self.label_list.append(label)
|
|
self.button_list.append(button)
|
|
|
|
def remove_item(self, item):
|
|
for label, button in zip(self.label_list, self.button_list):
|
|
if item == label.cget("text"):
|
|
label.destroy()
|
|
button.destroy()
|
|
self.label_list.remove(label)
|
|
self.button_list.remove(button)
|
|
return
|
|
|
|
|
|
class App(customtkinter.CTk):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
self.title("CTkScrollableFrame example")
|
|
self.grid_rowconfigure(0, weight=1)
|
|
self.columnconfigure(2, weight=1)
|
|
|
|
# create scrollable checkbox frame
|
|
self.scrollable_checkbox_frame = ScrollableCheckBoxFrame(master=self, width=200, command=self.checkbox_frame_event,
|
|
item_list=[f"item {i}" for i in range(50)])
|
|
self.scrollable_checkbox_frame.grid(row=0, column=0, padx=15, pady=15, sticky="ns")
|
|
self.scrollable_checkbox_frame.add_item("new item")
|
|
|
|
# create scrollable radiobutton frame
|
|
self.scrollable_radiobutton_frame = ScrollableRadiobuttonFrame(master=self, width=500, command=self.radiobutton_frame_event,
|
|
item_list=[f"item {i}" for i in range(100)],
|
|
label_text="ScrollableRadiobuttonFrame")
|
|
self.scrollable_radiobutton_frame.grid(row=0, column=1, padx=15, pady=15, sticky="ns")
|
|
self.scrollable_radiobutton_frame.configure(width=200)
|
|
self.scrollable_radiobutton_frame.remove_item("item 3")
|
|
|
|
# create scrollable label and button frame
|
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
self.scrollable_label_button_frame = ScrollableLabelButtonFrame(master=self, width=300, command=self.label_button_frame_event, corner_radius=0)
|
|
self.scrollable_label_button_frame.grid(row=0, column=2, padx=0, pady=0, sticky="nsew")
|
|
for i in range(20): # add items with images
|
|
self.scrollable_label_button_frame.add_item(f"image and item {i}", image=customtkinter.CTkImage(Image.open(os.path.join(current_dir, "test_images", "chat_light.png"))))
|
|
|
|
def checkbox_frame_event(self):
|
|
print(f"checkbox frame modified: {self.scrollable_checkbox_frame.get_checked_items()}")
|
|
|
|
def radiobutton_frame_event(self):
|
|
print(f"radiobutton frame modified: {self.scrollable_radiobutton_frame.get_checked_item()}")
|
|
|
|
def label_button_frame_event(self, item):
|
|
print(f"label button frame clicked: {item}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
customtkinter.set_appearance_mode("dark")
|
|
app = App()
|
|
app.mainloop()
|