Reputation: 6778
I am trying to display with a grid a table that is 270 rows and 70 columns It is apparently too big to display all in one shot. If I limit the rows to 50 it takes 12 seconds, then more as I increase of course, and then at some point it goes wonky. Is there to first set the label data for say 20 rows, then display, then set for the next 20, add those to the display, and so on?
def populate_using_tkinter(frame, project_list):
current_row_number = 0;
# Columns ********************************************************************************************************
label_id_column = Tkinter.Label(frame, text=Constants.PROJECT_COLUMN_TITLE_Id, borderwidth=GRID_BORDER_WIDTH, relief="solid", background=row_header_color)
<more columns>
label_ContractorID_column = Tkinter.Label(frame,text = Constants.PROJECT_COLUMN_TITLE_ContractorID, borderwidth = GRID_BORDER_WIDTH,relief = "solid")
label_id_column.grid(row=current_row_number, column=Constants.PROJECT_ID_COLUMN, sticky="nsew")
<more columns>
label_ContractorID_column.grid(row=current_row_number, column=Constants.PROJECT_ContractorID_COLUMN, sticky="nsew")
current_row_number +=1
frame.rowconfigure(current_row_number, minsize=row_height, weight=0)
for project in project_list:
project_id = project[0]
<more assignments>
project_ContractorID = project[70]
# Data ********************************************************************************************************
try:
label_project_id = Tkinter.Label(frame, text=project_id, borderwidth=GRID_BORDER_WIDTH, relief="solid", background=row_color)
<more data>
label_project_ContractorID=Tkinter.Label(frame,text=projectContractorID,anchor="w",borderwidth=GRID_BORDER_WIDTH,relief="solid", background=row_color)
label_project_id.grid(row=current_row_number, column=Constants.PROJECT_ID_COLUMN, sticky="nsew")
<more data>
label_project_ContractorID.grid(row=current_row_number, column=Constants.PROJECT_ContractorID_COLUMN, sticky="nsew")
except IndexError:
print ("[ERROR] IndexError: " + str(current_row_number) )
current_row_number +=1
def main():
project_list = <get from database> # 270 x 70
root = Tkinter.Tk()
canvas = Tkinter.Canvas(root, borderwidth=0, background="#ffffff")
frame = Tkinter.Frame(canvas, background="#ffffff")
canvas.pack(side="left", fill="both", expand=True)
canvas.create_window((4,4), window=frame, anchor="nw")
frame.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas))
populate_using_tkinter(frame, project_list)
root.geometry("1000x600")
root.mainloop()
Upvotes: 0
Views: 317
Reputation: 22503
This sounds like a job more suited for treeview
widget. But if you want to use a table of labels instead, one way is to use a generator combined with after
method:
import tkinter as tk
root = tk.Tk()
data = {i:i for i in range(200)}
def display_data():
row = 0
for k,v in data.items():
tk.Label(root,text=k).grid(row=row,column=0)
tk.Label(root,text=v).grid(row=row,column=1)
row+=1
if not row % 5: #configure this to display the number of rows each second
root.after(1000, fetch)
yield
a = display_data()
def fetch():
try:
next(a)
except StopIteration:
return
root.after(1000, fetch)
root.mainloop()
Or you can put it in a treeview
instead. Usually I find this easier to display data and it also comes in with many handy methods which allows you to sort, export etc. I also added both a vertical and horizontal scrollbar for reference.
from tkinter import ttk
import tkinter as tk
root = tk.Tk()
class TreeFrame(tk.Frame):
def __init__(self,master,**kwargs):
tk.Frame.__init__(self,master,**kwargs)
self.tree = ttk.Treeview(self, selectmode='extended', height=24)
self.tree.grid(row=0,column=0,sticky="nsew")
vsb = ttk.Scrollbar(self, orient="vertical",command=self.tree.yview)
vsb.grid(row=0,column=1,sticky="ns")
hsb = ttk.Scrollbar(self, orient="horizontal",command=self.tree.xview)
hsb.grid(row=1,column=0,sticky="ew")
self.tree.configure(yscrollcommand=vsb.set)
self.tree.configure(xscrollcommand=hsb.set)
header = [i for i in range(70)]
self.tree["columns"] = header
self.tree['show'] = 'headings'
self.start = 0
for i in range(len(header)):
self.tree.column(header[i], width=15, minwidth=27, anchor="w")
self.tree.heading(header[i], text=header[i], anchor='w')
def dummy_data(self):
for i in range(self.start, self.start+20):
current = self.tree.insert("","end",values=[i for _ in range(70)])
self.tree.see(current)
self.start += 20
if self.start >= 270:
return
else:
root.after(1000,self.dummy_data)
tree_frame = TreeFrame(root)
tree_frame.pack()
tk.Button(root,text="Add dummy data",command=tree_frame.dummy_data).pack()
root.mainloop()
Upvotes: 1