I've been looking for a good python module to work with tables. In the past, I made a personal C# project, and using tables was pretty straight forward.
I found out that my solution could be in dmnfarrell's "tkintertable" repo: https://github.com/dmnfarrell/tkintertable
I'm currently working with python 3.7
The default
Tcllib installed in my python3.7 isTcl8.6.
So I installed the repository and started to try it out, this is a short code snippet:
from tkintertable import TableCanvas, TableModel
from tkinter import *
from tkintertable.Testing import sampledata
data = sampledata()
"""data = {0: {'a': 0.85, 'b': 0.89, 'c': 0.01, 'd': 0.98, 'e': 0.88},
1: {'a': 0.14, 'b': 0.52, 'c': 0.68, 'd': 0.68, 'e': 0.74},
2: {'a': 0.75, 'b': 0.23, 'c': 0.92, 'd': 0.1, 'e': 0.42},
3: {'a': 0.15, 'b': 0.2, 'c': 0.37, 'd': 0.96,'e': 0.08},
4: {'a': 0.44, 'b': 0.41, 'c': 0.29, 'd': 0.16, 'e': 0.05},
5: {'a': 0.7, 'b': 0.52, 'c': 0.3, 'd': 0.55, 'e': 0.01},
6: {'a': 0.9, 'b': 0.63, 'c': 0.29, 'd': 0.66, 'e': 0.76},
7: {'a': 0.19, 'b': 0.78, 'c': 0.04, 'd': 0.67, 'e': 0.41},
8: {'a': 0.33, 'b': 0.94, 'c': 0.02, 'd': 0.38, 'e': 0.33},
9: {'a': 0.81, 'b': 0.58, 'c': 0.57, 'd': 0.9, 'e': 0.89}}
"""
table = TableCanvas(tframe,
data=data,
cellbackgr='#F1EFEF',
thefont=('Arial', 12),
rowheight=30,
bg="red",
reverseorder=1,
grid_color="black",
selectedcolor="gray",
multipleselectioncolor="#CCCCFF",
)
table.show()
At some point, this worked well but after a while, I started getting this error:
File "C:\MRES1\AppData\Roaming\Python\Python37\site-packages\tkintertable\Tables.py", line
1534, in drawGrid
fill=self.grid_color, width=self.linewidth)
File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 2489, in create_line
return self._create('line', args, kw)
File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 2477, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: bad screen distance "1.0"
So I started looking for this error and ran into this: Matplotlib - _tkinter.TclError: bad screen distance "320.0"
So I told to my self "let's try this" I didn't know where to change this so I ran (I know this might be a mistake) int to the implementation of the TableCanvas class and looked for the line given int the error log. That would be 1534.
File "C:\MRES1\AppData\Roaming\Python\Python37\site-packages\tkintertable\Tables.py", line 1534, in drawGrid fill=self.grid_color, width=self.linewidth)
Inside that class that's actually from dmnfarrell's repo I did a little change to make it work. I'm not saying this is a good practice at all but the error stopped.
Old
if self.vertlines==1:
for col in range(cols+1):
x=self.col_positions[col]
self.create_line(x,y_start,x,y_start+rows*h, tag='gridline',
fill=self.grid_color, width=self.linewidth)
if self.horizlines==1:
for row in range(startrow, endrow+1):
y_pos=y_start+row*h
self.create_line(x_start,y_pos,self.tablewidth,y_pos, tag='gridline',
fill=self.grid_color, width=self.linewidth)
New
if self.vertlines==1:
for col in range(cols+1):
x=self.col_positions[col]
self.create_line(x,y_start,x,y_start+rows*h, tag='gridline',
fill=self.grid_color, width=int(self.linewidth))
if self.horizlines==1:
for row in range(startrow, endrow+1):
y_pos=y_start+row*h
self.create_line(x_start,y_pos,self.tablewidth,y_pos, tag='gridline',
fill=self.grid_color, width=int(self.linewidth))
Notice that the only thing that changes is in the width field precisely on the int() convertion.
This approach worked fine till I changed my data to something little more realistic coming from an sqlite3 data base with a few more fields and elements. So I gave needed format to the data to populate my table and once again:
_tkinter.TclError: bad screen distance "1323.5"
But this time the error occurred in another part of the TableCanvas class so I basically went there and did the same that in the other case to fix this and worked fine again.
This is the exact part :
File "C:\Users\MRES1\AppData\Roaming\Python\Python37\site-packages\tkintertable\Tables.py", line 332, in redraw
self.configure(scrollregion=(0,0, self.table.tablewidth+self.table.x_start, self.height))
So once again I converted to int() the width used there:
self.tablewidth = int(self.tablewidth) # Basically here is where I make the convertion.
# The line below is where I figured to be a good starting point to deal with the error.
self.configure(scrollregion=(0,0, self.tablewidth+self.x_start, self.rowheight*self.rows+10))
I Know this might be one of the worst workarounds to fix this, I know I'm a newbie. Just want some advice from you guys to work properly with this module and if that's not possible it would be great if you could give me any advice.
I know I might not use the proper vocabulary, any advice on this is welcomed too. Thank you all!
For tables in tkinter you can also use the tkinter.ttk Treeview widget. However, please note that there are user interface limitations with this such as being unable to sort the data in the columns and being unable to change the colours. Please see the below code snippet i had written it has comments breaking down the code. You can copy the code to demo it yourself