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