Is there a way that the alternative row colouring can be maintained after sorting? My treeview has 2,000+ rows and would like to know if there is any solution other than retagging all the rows each time a column is sorted. When you click on any column, the row colouring gets mixed up.
Environment: Python 3.10.0 Windows 21H1
import tkinter as objTK
from tkinter import ttk as objTTK
from functools import partial
# Custom column sort for treeview
class MyTreeview(objTTK.Treeview):
def heading(self, column, sort_by=None, **kwargs):
if sort_by and not hasattr(kwargs, 'command'):
func = getattr(self, f"_sort_by_{sort_by}", None)
if func:
kwargs['command'] = partial(func, column, False)
# End of if
# End of if
return super().heading(column, **kwargs)
# End of heading()
def _sort(self, column, reverse, data_type, callback):
l = [(self.set(k, column), k) for k in self.get_children('')]
l.sort(key=lambda t: data_type(t[0]), reverse=reverse)
for index, (_, k) in enumerate(l):
self.move(k, '', index)
# End of for loop
self.heading(column, command=partial(callback, column, not reverse))
# End of _sort()
def _sort_by_name(self, column, reverse):
self._sort(column, reverse, str, self._sort_by_name)
# End of _sort_by_num()
# End of class MyTreeview
objWindow = objTK.Tk()
arrlbHeader = ["Type" , "Description"]
treeview = MyTreeview(columns=arrlbHeader, show="headings")
arrRows = [
["Expenses", "Gen"],
["Expenses", "Aug"],
["Expenses", "Aug"],
["Income", "Aug"],
["Expenses", "Aug"]
]
arrColWidth = [70, 80]
arrColAlignment = ["center", "e"]
# Column header and attributes
arrSortType = ["name", "name"]
for iCount in range(len(arrlbHeader)):
strHdr = arrlbHeader[iCount]
treeview.heading(strHdr, text=strHdr.title(), sort_by=arrSortType[iCount])
treeview.column(arrlbHeader[iCount], width=arrColWidth[iCount], stretch=True, anchor=arrColAlignment[iCount])
# End of for loop
treeview.pack()
# Row colouring tags
treeview.tag_configure("tgOddRow", background="white")
treeview.tag_configure("tgEvenRow", background="blue")
# Insert rows
for iCount in range(len(arrRows)):
if iCount % 2 == 0:
treeview.insert("", "end", values=arrRows[iCount], tags="tgEvenRow")
else:
treeview.insert("", "end", values=arrRows[iCount], tags="tgOddRow")
# End of for loop
objWindow.bind("<Escape>", lambda funcWinSer: objWindow.destroy())
objWindow.mainloop()