0
I have a listbox with multiple columns, as shown below.
I would like to sort the columns by clicking on the titles of them, see the code:
I had thought within the "sortby()" function to identify when they clicked on each title and so called an ordered list.
For this hypothesis I would need to update the variable "database" there at the end of the code and make the listbox load (update) the window. I can’t do this.
If you can help me, I’d like to thank you.
If you check another way, please inform me. Thank you.
import operator
try:
import Tkinter as tk
import tkFont
import ttk
except ImportError:
import tkinter as tk
import tkinter.font as tkFont
import tkinter.ttk as ttk
class MultiColumnListbox(object):
"""use a ttk.TreeView as a multicolumn ListBox"""
def __init__(self):
self.tree = None
self._setup_widgets()
self._build_tree()
def _setup_widgets(self):
container = ttk.Frame()
container.place(x=5, y=5, width=1170)
# create a treeview with dual scrollbars
self.tree = ttk.Treeview(columns=titulos_listbox, show="headings")
vsb = ttk.Scrollbar(orient="vertical",
command=self.tree.yview)
hsb = ttk.Scrollbar(orient="horizontal",
command=self.tree.xview)
self.tree.configure(yscrollcommand=vsb.set,
xscrollcommand=hsb.set)
self.tree.grid(column=0, row=0, sticky='nsew', in_=container)
vsb.grid(column=1, row=0, sticky='ns', in_=container)
hsb.grid(column=0, row=1, sticky='ew', in_=container)
container.grid_columnconfigure(0, weight=1)
container.grid_rowconfigure(0, weight=1)
def _build_tree(self):
for col in titulos_listbox:
self.tree.heading(col, text=col.title(),
command=lambda c=col: sortby(self.tree, c, 0))
# adjust the column's width to the header string
self.tree.column(col,
width=tkFont.Font().measure(col.title()))
for item in banco_dados:
self.tree.insert('', 'end', values=item)
def sortby(tree, col, descending):
"""sort tree contents when a column header is clicked on"""
data = [(tree.set(child, col), child) \
for child in tree.get_children('')]
if col == "Data":
print("Data")
# bd = sorted(banco_dados, key=operator.itemgetter(0)) # sem alterar a lista
bd = banco_dados.sort(key=operator.itemgetter(0)) # alterando a lista
print(banco_dados)
elif col == "Código":
print("Código")
# bd = sorted(banco_dados, key=operator.itemgetter(1))# sem alterar a lista
bd = banco_dados.sort(key=operator.itemgetter(1)) # alterando a lista
print(banco_dados)
elif col == "Item":
print("Item")
# bd = sorted(banco_dados, key=operator.itemgetter(2))# sem alterar a lista
bd = banco_dados.sort(key=operator.itemgetter(2)) # alterando a lista
print(banco_dados)
elif col == "Quantidade":
print("Quantidade")
# bd = sorted(banco_dados, key=operator.itemgetter(3))# sem alterar a lista
bd = banco_dados.sort(key=operator.itemgetter(3)) # alterando a lista
print(banco_dados)
elif col == "Custo unitário":
print("Custo unitário")
# bd = sorted(banco_dados, key=operator.itemgetter(4))# sem alterar a lista
bd = banco_dados.sort(key=operator.itemgetter(4)) # alterando a lista
print(banco_dados)
elif col == "Custo total":
print("Custo total")
# bd = sorted(banco_dados, key=operator.itemgetter(5))# sem alterar a lista
bd = banco_dados.sort(key=operator.itemgetter(5)) # alterando a lista
print(banco_dados)
titulos_listbox = ['Data', 'Código', 'Item', 'Quantidade', 'Custo unitário', 'Custo total']
banco_dados = [('01/01/2019', 000, 'item 000', 555, 666.0, 9999999.0, ''),
('01/01/2019', 111, 'item 111', 111, 111.0, 111.0, 'obs1'),
('02/01/2019', 333, 'item 333', 222, 222.0, 222.0, 'obs2'),
('03/01/2019', 777, 'item 777', 333, 333.0, 333.0, 'obs 3'),
('04/01/2019', 444, 'item 444', 4444, 4444.0, 4444.0, 'obs 4'),
('05/01/2019', 222, 'item 222', 5555, 5555.0, 5555.0, 'obs 5'),
('06/01/2019', 888, 'item 888', 6666, 6666.0, 6666.0, 'obs 6')]
if __name__ == '__main__':
root = tk.Tk()
root.title("listbox")
root["bg"] = "LightSteelBlue"
root.geometry('1180x255+5+40')
listbox = MultiColumnListbox()
root.mainloop()
Thank you @alandplm I was since 9 am trying.
– Wilson Junior
Thanks to @Wilsonjunior!
– user148747