Search code examples
pythontkintersqlitetreeview

How to delete record from tkinter treeview to apply the changes in sqlite3


Am trying to delete record displayed in tkinter treeview by using the tree.selection() method. I want the selected row in the treeview selected to also be deleted from the sqlite3db also but when i select row to be deleted i received this error

_tkinter.TclError: Item I not found

i found this link on the site but i doesn't answer my talent.

from tkinter import ttk
import tkinter as tk
import sqlite3


def connect():
    conn = sqlite3.connect("TRIAL.db")
    cur = conn.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS profile(id INTEGER PRIMARY KEY, 
First TEXT, Surname TEXT)")
    conn.commit()
    conn.close()


def Delete():
    selected_item = tree.selection()[0]

    print(selected_item)  # it prints the selected row id

    conn = sqlite3.connect("TRIAL.db")
    cur = conn.cursor()
    cur.execute("DELETE FROM profile WHERE id=?", (selected_item,))
    conn.commit()

    for b in selected_item:
        tree.delete(b)

    conn.close()


connect()  #  this to create the db

root = tk.Tk()
root.geometry("400x400")

tree= ttk.Treeview(root, column=("column1", "column2", "column3"), 
show='headings')
tree.heading("#1", text="NUMBER") 
tree.heading("#2", text="FIRST NAME")
tree.heading("#3", text="SURNAME")
tree.pack()


b2 = tk.Button(text="DELETE FROM PARTICULAR DATA TREEVIEW AND SQLITE3", 
command=Delete)
b2.pack(side=tk.BOTTOM)

root.mainloop()

Solution

  • There are three problems in your Delete function:

    • First, you do

      for b in selected_item:
          tree.delete(b)
      

      but selected_item is a string, so you iterate over the characters of the item id. I think that what you wanted to do was to iterate over the selected items, something like:

      for selected_item in tree.selection():
          tree.delete(selected_item)
      
    • Secondly, you try to delete the db entry with

      cur.execute("DELETE FROM profile WHERE id=?", (selected_item,))
      

      but selected_item is the item id in the tree, not in the db. The db id is the one in the first column and you can get it with

      tree.set(selected_item, '#1')
      
    • Finally, the line selected_item = tree.selection()[0] is going to throw an error if there is no selected item, but if what you want is to remove all selected items, then you no longer need this line (see code below).

    Here is the full function:

    def Delete():
        conn = sqlite3.connect("TRIAL.db")
        cur = conn.cursor()
        for selected_item in tree.selection():
            print(selected_item)  # it prints the selected row id
            cur.execute("DELETE FROM profile WHERE id=?", (tree.set(selected_item, '#1'),))
            conn.commit()
            tree.delete(selected_item)
        conn.close()