83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
import customtkinter as ctk
|
|
|
|
from ..utils import fonts
|
|
|
|
|
|
class CTkTableFrame(ctk.CTkFrame):
|
|
def __init__(self, master: ctk.CTk, columns, data, callback, width=400, height=200, *args, **kwargs):
|
|
super().__init__(master, *args, **kwargs)
|
|
self.columns = columns
|
|
self.data = data
|
|
|
|
self._callback = callback
|
|
|
|
self.configure(width=width, height=height)
|
|
|
|
self.scroll_frame = ctk.CTkScrollableFrame(self)
|
|
self.scroll_frame.pack(fill="both", expand=True, padx=5, pady=5)
|
|
|
|
self._create_table()
|
|
|
|
def _create_table(self):
|
|
# Заголовки
|
|
header_frame = ctk.CTkFrame(self.scroll_frame, fg_color="gray30")
|
|
header_frame.pack(fill="x", padx=2, pady=1)
|
|
|
|
for col in self.columns:
|
|
header_label = ctk.CTkLabel(header_frame, text=col, font=fonts.body_med_font(), padx=5)
|
|
header_label.pack(side="left", padx=5, pady=3, expand=True)
|
|
|
|
# Данные
|
|
for row_data in self.data:
|
|
row_frame = ctk.CTkFrame(self.scroll_frame, fg_color="gray20", corner_radius=3, height=20)
|
|
row_frame.pack(fill="x", padx=2, pady=1)
|
|
|
|
# Обработчик двойного клика
|
|
row_frame.bind("<Double-1>", lambda event, r=row_data: self._callback(r))
|
|
|
|
for cell in row_data:
|
|
cell_label = ctk.CTkLabel(row_frame, text=cell, font=fonts.small_font(), padx=5)
|
|
cell_label.pack(side="left", padx=5, pady=2, expand=True)
|
|
|
|
# Прокидываем клик от ячеек на строку
|
|
cell_label.bind("<Double-1>", lambda event, r=row_data: self._callback(r))
|
|
|
|
|
|
# Пример использования
|
|
if __name__ == "__main__":
|
|
|
|
app = ctk.CTk()
|
|
app.geometry("600x400")
|
|
|
|
def show_modal(row_data):
|
|
modal = ctk.CTkToplevel(app)
|
|
modal.geometry("250x150")
|
|
modal.title("Детали")
|
|
|
|
# Делаем модальное окно поверх основного
|
|
modal.grab_set()
|
|
modal.focus_force()
|
|
|
|
label_text = f"{row_data}"
|
|
label = ctk.CTkLabel(modal, text=label_text, font=("Arial", 12))
|
|
label.pack(pady=15)
|
|
|
|
close_btn = ctk.CTkButton(modal, text="Закрыть", command=modal.destroy)
|
|
close_btn.pack(pady=10)
|
|
|
|
ctk.set_appearance_mode("dark")
|
|
|
|
columns = ["ID", "Имя", "Логин"]
|
|
data = [(i, f"Имя {i}", f"i1111-{i}") for i in range(1, 21)] # 20 строк для теста скролла
|
|
|
|
lable = ctk.CTkLabel(app, text="Тестовая таблица", font=fonts.title_font())
|
|
lable.pack(pady=10)
|
|
|
|
table = CTkTableFrame(app, columns, data, show_modal, width=400, height=200)
|
|
table.pack(pady=10, padx=20, fill="both", expand=True)
|
|
|
|
but1 = ctk.CTkButton(app, text="Закрыть", command=app.destroy)
|
|
but1.pack(pady=10)
|
|
|
|
app.mainloop()
|