Interface-module/frames/CTkTableFrame.py
2025-03-18 13:17:29 +03:00

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()