pythonpython-3.xtkinterpython-3.5

Tkinter - Deleting rows from a grid dynamically


I have some code that reads a .csv file and then displays the content using grids and iterating through rows/columns to pack them, like so:

from tkinter import *
import csv

def createStandardTable(f,window):
    global trow
    global table
    global w
    global sizes
    global record
    global column
    handle = csv.reader(f)
    length = len(next(handle))

    sizes = [0] * length
    for record in handle:

        for p,column in enumerate(record):
            if len(column) > sizes[p]:
                sizes[p] = len(column)+3

    f.seek(0)
    trow = 0
    table = Frame(window)
    for record in handle:
        for w,column in enumerate(record):
            print(w)
            setText = StringVar()
            Entry(table,textvariable=setText,width=sizes[w]+5,relief="groove",justify=LEFT, background='white').grid(column=w,row=trow,sticky=W)
            setText.set(column)

        trow+=1
    return table

def delete_row():
    l=list(table.grid_slaves(row=trow))
    print(l)
    for w in l:
        w.grid_forget()

def new_row():
    global trow
    for w,column in enumerate(record):
        Entry(table,textvariable="",width=sizes[w]+5,relief="groove",justify=LEFT, background='white').grid(column=w,row=trow,sticky=W)
        print (trow)
    trow+=1

root = Tk()
f = open("example.csv")
newButton = Button(text='new row', command=new_row)
deleteButton = Button(text='delete row', command='delete_row')
newtable = createStandardTable(f,root)
newtable.pack()
newButton.pack()
deleteButton.pack()
root.mainloop()

example.csv looks something like this:

ID  | Name | username | password
1234| Bob  | test123  | l98762

When the "new row" button is pressed it successfully creates a new row. However, whenever the "delete row" button is pressed it doesn't delete the most recent row and I don't understand why not?

Can someone please explain what's wrong? Thanks.


Solution

  • I can't test it since you didn't provide a working example, but the first thing I notice is that you increment trow after you add the row, so the last row is trow - 1. Since you'll need to decrement it anyway just do that before you try to delete.

    def delete_row():
        trow -= 1
        l=list(table.grid_slaves(row=trow))
        for w in l:
            w.grid_forget()
    

    Or better yet, forget using your own variable and use table.grid_size() to find the row to add or delete.

    Edit: also you seem to be passing a string, not a function, to the button. Change that line to:

    deleteButton = Button(text='delete row', command=delete_row)