I want to load the data from a CSV file which have around 20,000 records and want to display it in tkinter in a scrollable table format. I used canvas, labels, grids, and scrollbar to achieve this. However, it can load only around 100-300 records in Tkinter without hanging. What could be the possible reason for this? I find that parsing through CSV is not the culprit. Is it the canvas and scrollable area? Can Tkinter show huge data as tables?
class Table(Frame):
def __init__(self, parent, csv_data, start=0):
Frame.__init__(self, parent, background="#EEEEEE", height=400)
self._widgets = []
self._canvas = Canvas(self, width=1300, height=500)
self._canvas.grid(row=0, column=0, sticky="news") # changed
self._vertical_bar = Scrollbar(self, orient="vertical", command=self._canvas.yview)
self._vertical_bar.grid(row=0, column=1, sticky="ns")
self._canvas.configure(yscrollcommand=self._vertical_bar.set)
self._horizontal_bar = Scrollbar(self, orient="horizontal", command=self._canvas.xview)
self._horizontal_bar.grid(row=1, column=0, sticky="we")
self._canvas.configure(xscrollcommand=self._horizontal_bar.set)
self.frame = Frame(self._canvas)
self._canvas.create_window((0, 0), window=self.frame, anchor="nw")
self.frame.bind("<Configure>", self.resize)
lineNum = start-1;
for row in csv_data:
print(lineNum)
lineNum += 1;
if lineNum < start:
continue;
if lineNum == start+200:
break;
current_row = []
#index
for column in range(len(row)+1):
v = StringVar()
label = Label(self.frame, textvariable=v)
label.config(font=("Calibri", 10), background="white",highlightcolor='white', highlightbackground='white', borderwidth=0)
label.grid(row=lineNum, column=column+1, sticky="nsew", padx=1, pady=1)
current_row.append(label)
if column == 0:
v.set(lineNum)
else:
v.set(row[column-1])
self._widgets.append(current_row)
for column in range(lineNum):
self.grid_columnconfigure(column, weight=1)
def resize(self, event=None):
self._canvas.configure(scrollregion=self._canvas.bbox("all"))
#self._canvas.itemconfig(self.frame, height=500, width=1300)
#self.__canvas.itemconfigure("self.frame", width=1300)
def set(self, row, column, value):
widget = self._widgets[row][column]
widget.configure(text=value)