Closed H1B0B0 closed 1 year ago
I found a solution ! In fact, when you create a new line it deletes all the old lines and that's what was causing the problem I was having. now I make sure to create only 1 single line each time, but the code slows down when the tags pile up so I have to optimize it a bit to get better performance.
def add_row(self, values, index=None):
""" add a new row """
if index is None:
index = len(self.values)
self.values.insert(index, values)
self.rows += 1
for i in range(self.columns):
if self.phase == "rows":
if index % 2 == 0:
fg = self.fg_color
else:
fg = self.fg_color2
else:
if i % 2 == 0:
fg = self.fg_color
else:
fg = self.fg_color2
if self.header_color:
if index == 0:
fg = self.header_color
corner_radius = self.corner
if index == 0 and i == 0:
corners = ["", fg, fg, fg]
elif index == self.rows - 1 and i == self.columns - 1:
corners = [fg, fg, "", fg]
elif index == self.rows - 1 and i == 0:
corners = [fg, fg, fg, ""]
elif index == 0 and i == self.columns - 1:
corners = [fg, "", fg, fg]
else:
corners = [fg, fg, fg, fg]
corner_radius = 0
value = values[i] if i < len(values) else " "
self.data = {"row": index, "column": i, "value": value}
self.frame[index, i] = customtkinter.CTkButton(
self,
background_corner_colors=corners,
corner_radius=corner_radius,
fg_color=fg,
hover=self.hover,
text=value,
command=(lambda e=self.data: self.command(e)) if self.command else None,
)
self.frame[index, i].grid(
column=i, row=index, padx=self.padx, pady=self.pady, sticky="nsew"
)
self.rowconfigure(index, weight=1)
self.update_idletasks()
@H1B0B0 I don't know what to implement, this library is not that performance friendly because of so many ctkbuttons. I will try to implement a new method for the cells.
Hello thank for the response. Actually I have this code it's a little bit more fast but it's not full optimised.
import customtkinter
class CTkTable(customtkinter.CTkFrame):
def __init__(
self,
master: any = None,
row: int = None,
column: int = None,
padx: int = 1,
pady: int = 0,
values: list = [[None]],
colors: list = [None, None],
color_phase: str = "rows",
header_color: str = None,
corner_radius: int = 25,
hover: bool = False,
command = None,
**kwargs):
super().__init__(master, fg_color="transparent")
self.master = master
self.rows = row if row else len(values)
self.columns = column if column else len(values[0])
self.padx = padx
self.pady = pady
self.command = command
self.values = values
self.colors = colors
self.header_color = header_color
self.phase = color_phase
self.corner = corner_radius
self.hover = hover
self.fg_color = customtkinter.ThemeManager.theme["CTkFrame"]["fg_color"] if not self.colors[0] else self.colors[0]
self.fg_color2 = customtkinter.ThemeManager.theme["CTkFrame"]["top_fg_color"] if not self.colors[1] else self.colors[1]
if self.colors[0] is None and self.colors[1] is None:
if self.fg_color==self.master.cget("fg_color"):
self.fg_color = customtkinter.ThemeManager.theme["CTk"]["fg_color"]
if self.fg_color2==self.master.cget("fg_color"):
self.fg_color2 = customtkinter.ThemeManager.theme["CTk"]["fg_color"]
self.widgets = []
self.draw_table(**kwargs)
def draw_table(self, **kwargs):
""" draw the table """
for i in range(len(self.values)):
row_widgets = []
for j in range(len(self.values[i])):
if self.phase == "rows":
if i % 2 == 0:
fg = self.fg_color
else:
fg = self.fg_color2
else:
if j % 2 == 0:
fg = self.fg_color
else:
fg = self.fg_color2
if self.header_color:
if i == 0:
fg = self.header_color
corner_radius = self.corner
if i == 0 and j == 0:
corners = ["", fg, fg, fg]
elif i == len(self.values) - 1 and j == len(self.values[i]) - 1:
corners = [fg, fg, "", fg]
elif i == len(self.values) - 1 and j == 0:
corners = [fg, fg, fg, ""]
elif i == 0 and j == len(self.values[i]) - 1:
corners = [fg, "", fg, fg]
else:
corners = [fg, fg, fg, fg]
corner_radius = 0
value = self.values[i][j] if i < len(self.values) and j < len(self.values[i]) else " "
widget = customtkinter.CTkLabel(
self,
corner_radius=corner_radius,
fg_color=fg,
text=value,
**kwargs
)
widget.grid(column=j, row=i, padx=self.padx, pady=self.pady, sticky="nsew")
row_widgets.append(widget)
self.widgets.append(row_widgets)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
def edit_row(self, row, **kwargs):
"""Edit all parameters of a single row"""
row_widgets = self.widgets[row]
for i, widget in enumerate(row_widgets):
widget.configure(**kwargs)
def edit_column(self, column, **kwargs):
"""Edit all parameters of a single column"""
for i in range(self.rows):
widget = self.widgets[i][column]
widget.configure(**kwargs)
def update_values(self, values, **kwargs):
""" update all values at once """
self.values = values
for i in range(len(self.values)):
for j in range(len(self.values[i])):
self.widgets[i][j].configure(text=self.values[i][j], **kwargs)
def add_row(self, values, index=None):
""" add a new row """
if index is None:
index = len(self.values)
self.values.insert(index, values)
self.rows += 1
row_widgets = []
for i in range(self.columns):
if self.phase == "rows":
if index % 2 == 0:
fg = self.fg_color
else:
fg = self.fg_color2
else:
if i % 2 == 0:
fg = self.fg_color
else:
fg = self.fg_color2
if self.header_color:
if index == 0:
fg = self.header_color
corner_radius = self.corner
if index == 0 and i == 0:
corners = ["", fg, fg, fg]
elif index == self.rows - 1 and i == self.columns - 1:
corners = [fg, fg, "", fg]
elif index == self.rows - 1 and i == 0:
corners = [fg, fg, fg, ""]
elif index == 0 and i == self.columns - 1:
corners = [fg, "", fg, fg]
else:
corners = [fg, fg, fg, fg]
corner_radius = 0
value = values[i] if i < len(values) else " "
data = {"row": index, "column": i, "value": value}
widget = customtkinter.CTkLabel(
self,
corner_radius=corner_radius,
fg_color=fg,
text=value,
)
widget.grid(column=i, row=index, padx=self.padx, pady=self.pady, sticky="nsew")
row_widgets.append(widget)
self.widgets.insert(index, row_widgets)
self.rowconfigure(index, weight=1)
def add_column(self, values, index=None):
"""Add a new column"""
if index is None:
index = len(self.values[0])
for row_values, row_widgets in zip(self.values, self.widgets):
row_values.insert(index, None)
if self.phase == "columns":
if index % 2 == 0:
fg = self.fg_color
else:
fg = self.fg_color2
else:
if index % 2 == 0:
fg = self.fg_color
else:
fg = self.fg_color2
if self.header_color:
if index == 0:
fg = self.header_color
corner_radius = self.corner
if index == 0 and row_widgets[0] == self.widgets[0][0]:
corners = ["", fg, fg, fg]
elif index == self.columns and row_widgets[-1] == self.widgets[-1][0]:
corners = [fg, fg, "", fg]
elif index == self.columns and row_widgets[0] == self.widgets[-1][0]:
corners = [fg, fg, fg, ""]
elif index == 0 and row_widgets[-1] == self.widgets[0][-1]:
corners = [fg, "", fg, fg]
else:
corners = [fg, fg, fg, fg]
corner_radius = 0
value = values[row_values.index(None)] if None in row_values else " "
data = {"row": row_values.index(None), "column": index, "value": value}
widget = customtkinter.CTkLabel(
self,
corner_radius=corner_radius,
fg_color=fg,
text=value,
)
widget.grid(column=index, row=row_widgets[0].grid_info()["row"], padx=self.padx, pady=self.pady, sticky="nsew")
row_widgets.insert(index, widget)
self.columns += 1
self.columnconfigure(index, weight=1)
def delete_row(self, index):
""" delete a row """
if index < len(self.values):
del self.values[index]
row_widgets = self.widgets.pop(index)
for widget in row_widgets:
widget.destroy()
self.rows -= 1
def delete_column(self, index):
"""Delete a column"""
if index < len(self.values[0]):
for row_values, row_widgets in zip(self.values, self.widgets):
del row_values[index]
widget = row_widgets.pop(index)
widget.destroy()
self.columns -= 1
def insert(self, row, column, value, **kwargs):
widget = self.widgets[row][column]
widget.configure(text=value, **kwargs)
def delete(self, row, column, **kwargs):
""" delete a value from a specific block [row, column] """
self.widgets[row][column].configure(text="", **kwargs)
def get(self):
return self.values
def get_value(self, row, column):
return self.widgets[row][column].cget("text")
def configure(self, **kwargs):
""" configure table widget attributes"""
if "colors" in kwargs:
self.colors = kwargs.pop("colors")
self.fg_color = self.colors[0]
self.fg_color2 = self.colors[1]
if "header_color" in kwargs:
self.header_color = kwargs.pop("header_color")
if "rows" in kwargs:
self.rows = kwargs.pop("rows")
if "columns" in kwargs:
self.columns = kwargs.pop("columns")
if "values" in kwargs:
self.values = kwargs.pop("values")
if "padx" in kwargs:
self.padx = kwargs.pop("padx")
if "pady" in kwargs:
self.pady = kwargs.pop("pady")
self.update_values(self.values, **kwargs)
Currently I am working on a method to create all cells in a row at once and not one by one.
@H1B0B0 Replacing the cells with CTkLabel will remove many functionalities.
I know but I have no choice since I only need a single table capable of displaying 8 columns and an ultra large number of rows.
Here you can the my and why I have some problemes with table optimisation. The Timestamp, lastseentime, rssi and phase angle and for finish counter are dynamics.
@H1B0B0 Thats a lot of data in that table. Try something like tksheet if you want optimisation: https://github.com/ragardner/tksheet
I have fund a solution but thank for your help
Hello I have a problem with my code I try to create a row in the table for each tag read with per column each time the corresponding info. but when I add a new line this one appears and then triggers an error which erases the entire table. The error:
and my code is that :
I create the Table and after that i give the table object to my fonction. in my fonction i make that :