2

Currently I am using a Treeview. The problem is that I am using quite a large data set. So that the GUI isn't massive, I've limited the size of the Treeview to fit the window and added vertical and horizontal scrollbars. It displays the data exactly how I want, however there are speed issues when scrolling in each direction. Is there a better/faster way to display spreadsheet-like data.

Roars
  • 623
  • 5
  • 17
  • Do you need users to be able to update cells in the spreadsheet or is all the data static and loaded/calculated by the program? – Ethan Field Sep 25 '17 at 12:27
  • @EthanField Having editable data would be nice. However, if having static data would make it a lot faster I would definitely open to a static approach. – Roars Sep 25 '17 at 13:50
  • 1
    Both are possible and both should perform very well in terms of responsiveness, however having editable forms is a lot more in depth. Is there a reason why Excel wouldn't suffice for the purpose if you do require them to be directly inputtable? – Ethan Field Sep 25 '17 at 14:00

2 Answers2

4

The below solution is cobbled together but should achieve the desired result:

from tkinter import *

class App:
    def __init__(self, root):
        self.entry = []
        self.sv = []
        self.root = root
        self.canvas = Canvas(self.root, background="#ffffff", borderwidth=0)
        self.frame = Frame(self.canvas, background="#ffffff")
        self.scrolly = Scrollbar(self.root, orient="vertical", command=self.canvas.yview)
        self.scrollx = Scrollbar(self.root, orient="horizontal", command=self.canvas.xview)
        self.canvas.configure(yscrollcommand=self.scrolly.set)#, xscrollcommand=self.scrollx.set)
        self.canvas.create_window((4,4), window=self.frame, anchor="nw", tags="self.frame")
        self.scrolly.pack(side="left", fill="y")
        self.canvas.pack(side="top", fill="both", expand=True)
        self.scrollx.pack(side="bottom", fill="x")
        self.frame.bind("<Configure>", self.onFrameConfigure)
        for i in range(15):
            self.entry.append([])
            self.sv.append([])
            for c in range(30):
                self.sv[i].append(StringVar())
                self.sv[i][c].trace("w", lambda name, index, mode, sv=self.sv[i][c], i=i, c=c: self.callback(sv, i, c))
                self.entry[i].append(Entry(self.frame, textvariable=self.sv[i][c]).grid(row=c, column=i))
    def onFrameConfigure(self, event):
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))
    def callback(self, sv, column, row):
        print("Column: "+str(column)+", Row: "+str(row)+" = "+sv.get())

root = Tk()
App(root)
root.mainloop()
Ethan Field
  • 4,646
  • 3
  • 22
  • 43
4

I ended up using pandastable (https://github.com/dmnfarrell/pandastable). As it provided a quick and easy way of displaying data in a spreadsheet like manner. It also provides a lot of built in functionality, such as: sorting, filtering and applying functions to columns

Roars
  • 623
  • 5
  • 17
  • 2
    amazing that it's basically a tkinter canvas with straight lines and text drawn, real shame that someone developing tcl has not written a proper table widget in C for tkinter – ragardner Oct 18 '17 at 22:05