OK, here’s the sample code. Double-click on a row to edit it:
from os.path import dirname, join
import tkinter as tk
import tkinter.ttk as ttk
class EditDialog(tk.Toplevel):
def __init__(self, parent, row):
tk.Toplevel.__init__(self, parent)
self.title('Edit row')
self.grab_set()
self.parent = parent
self.row = row
# Use a grid layout.
self.grid_columnconfigure(0, weight=0)
self.grid_columnconfigure(1, weight=1)
# The entry boxes.
tk.Label(self, text='cl_broj:').grid(row=0, column=0)
self.cl_broj_entry = tk.Entry(self)
self.cl_broj_entry.grid(row=0, column=1, sticky='we')
tk.Label(self, text='ime:').grid(row=1, column=0)
self.ime_entry = tk.Entry(self)
self.ime_entry.grid(row=1, column=1, sticky='we')
tk.Label(self, text='prezime:').grid(row=2, column=0)
self.prezime_entry = tk.Entry(self)
self.prezime_entry.grid(row=2, column=1, sticky='we')
tk.Label(self, text='ured:').grid(row=3, column=0)
self.ured_entry = tk.Entry(self)
self.ured_entry.grid(row=3, column=1, sticky='we')
tk.Label(self, text='poduzece:').grid(row=4, column=0)
self.poduzece_entry = tk.Entry(self)
self.poduzece_entry.grid(row=4, column=1, sticky='we')
tk.Label(self, text='dolazak:').grid(row=5, column=0)
self.dolazak_entry = tk.Entry(self)
self.dolazak_entry.grid(row=5, column=1, sticky='we')
tk.Label(self, text='odlazak:').grid(row=6, column=0)
self.odlazak_entry = tk.Entry(self)
self.odlazak_entry.grid(row=6, column=1, sticky='we')
tk.Label(self, text='nocenja:').grid(row=7, column=0)
self.nocenja_entry = tk.Entry(self)
self.nocenja_entry.grid(row=7, column=1, sticky='we')
# The OK and Cancel buttons.
frame = tk.Frame(self)
frame.grid(row=8, column=0, columnspan=2, sticky='we')
tk.Button(frame, text='Cancel', command=self.on_cancel).pack(side='right')
tk.Button(frame, text='OK', command=self.on_ok).pack(side='right')
self.bind('<Return>', self.on_ok)
self.bind('<Escape>', self.on_cancel)
# Fill the entry boxes.
self.cl_broj_entry.insert(0, self.row['cl_broj'])
self.ime_entry.insert(0, self.row['ime'])
self.prezime_entry.insert(0, self.row['prezime'])
self.ured_entry.insert(0, self.row['ured'])
self.poduzece_entry.insert(0, self.row['poduzece'])
self.dolazak_entry.insert(0, self.row['dolazak'])
self.odlazak_entry.insert(0, self.row['odlazak'])
self.nocenja_entry.insert(0, self.row['nocenja'])
self.ok = False
def on_ok(self, event=None):
self.row['cl_broj'] = self.cl_broj_entry.get()
self.row['ime'] = self.ime_entry.get()
self.row['prezime'] = self.prezime_entry.get()
self.row['ured'] = self.ured_entry.get()
self.row['poduzece'] = self.poduzece_entry.get()
self.row['dolazak'] = self.dolazak_entry.get()
self.row['odlazak'] = self.odlazak_entry.get()
self.row['nocenja'] = self.nocenja_entry.get()
self.ok = True
self.destroy()
def on_cancel(self, event=None):
self.ok = False
self.destroy()
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title('CSV Table Viewer')
self.state('zoomed')
# Make a table from a TreeView and add scrollbars.
self.grid_rowconfigure(0, weight=1)
self.grid_rowconfigure(1, weight=0)
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=0)
yscrollbar = tk.Scrollbar(self, orient='vertical')
yscrollbar.grid(row=0, column=1, sticky='ns')
xscrollbar = tk.Scrollbar(self, orient='horizontal')
xscrollbar.grid(row=1, column=0, sticky='we')
self.table = ttk.Treeview(self, show='headings', selectmode='extended', xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set)
self.table.grid(row=0, column=0, sticky='nswe')
# Double-click on a row to edit it.
self.table.bind('<Double-1>', self.on_edit_row)
# Load the data from a CSV file.
self.data_path = join(dirname(__file__), 'data.csv')
self.load_data()
# Add headings to the table.
headings = self.fieldnames
self.table['columns'] = headings
for i, heading in enumerate(headings):
self.table.heading(i, text=heading)
# Fill the table.
for row in self.rows:
values = self.make_values(row)
# The 'iid' entry is the ID of the row in the table.
row['iid'] = self.table.insert('', 'end', values=values)
# Make a lookup dict that maps the ID of a row to the row's data.
self.row_by_iid = {row['iid']: row for row in self.rows}
def load_data(self):
# Load the data from the CSV file.
try:
with open(self.data_path, encoding='utf-8') as file:
reader = csv.DictReader(file)
self.fieldnames = reader.fieldnames
self.rows = list(reader)
except FileNotFoundError:
# No CSV file, so make up some data.
self.fieldnames = ['cl_broj', 'ime', 'prezime', 'ured', 'poduzece', 'dolazak', 'odlazak', 'nocenja']
self.rows = []
for i in range(1, 11):
row = {fieldname: f'{fieldname} {i}' for fieldname in self.fieldnames}
self.rows.append(row)
def make_values(self, row):
return [row[fieldname] for fieldname in self.fieldnames]
def on_edit_row(self, event=None):
# Which row are we editing?
selection = self.table.selection()
if len(selection) != 1:
return
row = self.row_by_iid[selection[0]]
dialog = EditDialog(self, row)
dialog.wait_window()
if dialog.ok:
# The dialog's OK button was clicked, so the data has changed.
# Update the table.
values = self.make_values(row)
self.table.item(row['iid'], values=values)
App().mainloop()