简体   繁体   中英

Delete item selected from treeview in tkinter

I have a json that shows me its content in a treeview. Currently I have a function that selects the item and deletes it, but it only deletes it in the treeview and it is not updated in the json. My question is how to call the json in this function to update and delete the selected item.

this function deletes the item in the treeview

def borrar_select():
        borrar1 = json_tree.selection()[0]
        json_tree.delete(borrar1)

I tried to call the json to read it and write in this function.

def borrar_select():
    with open('prueba1.json', "r") as f:
        data = json.load(f)

    for record in data['Clientes']:
        borrar1 = json_tree.selection()[0]
        json_tree.delete(borrar1)

    with open('prueba1.json', "w") as f:
        json.dump(record,f,indent=4)

Actually, it deletes the selected row in the treeview but in the console I get the following error.

PS C:\Users\*\Desktop\Tkinter> & E:/Prog/Python3/Python311/python.exe c:/Users/*/Desktop/Tkinter/test1.py
Exception in Tkinter callback
Traceback (most recent call last):
  File "E:\Prog\Python3\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "c:\Users\*\Desktop\Tkinter\test1.py", line 102, in borrar_select
    borrar1 = json_tree.selection()[0]
              ~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: tuple index out of range

Consequently, the modification is not saved in the json either.

I use python very recently so I would like if someone can give me a hand to solve this.

This is a example of how it works

import json
from tkinter import ttk
from tkinter import *
import tkinter as tk

ventana = tk.Tk()
ventana.title("Test")
ventana.geometry("1000x600")

frame1 = tk.Frame(ventana, bg="green", height=300, width=700)
frame1.grid(row=1, column=0)

frame2 = tk.Frame(ventana, bg="yellow", height=300, width=700)
frame2.grid(row=2, column=0)

frame_entry = tk.Frame(frame2) #Frame para los entry
frame_entry.pack(pady=20)
    
tree_frame = tk.Frame(frame1) #Frame para el arbol
tree_frame.pack(pady=20)

#style del tree
style = ttk.Style()
style.theme_use("clam")
style.configure("Treeview", background="#c7c7c7", foreground="black", rowheight=25,fieldbackground="#a1a1a1")
style.map("Treeview", background=[('selected','green')])

tree_scroll = Scrollbar(tree_frame) #Frame para el scrollbar del arbol
tree_scroll.pack(side=RIGHT, fill=Y)
#Lista Treeview
json_tree = ttk.Treeview(tree_frame, yscrollcommand=tree_scroll.set)
json_tree.pack()

#config scroll
tree_scroll.config(command=json_tree.yview)

#Definir columnas
json_tree['column'] = ("Logo", "Name", "Last Name", "Something")

#Formato columnas
json_tree.column("#0", width=0, minwidth=0)#Columna Fantasma
json_tree.column("Logo", anchor="w", width=120)
json_tree.column("Name", anchor="w", width=120)
json_tree.column("Last Name", anchor="w", width=120)
json_tree.column("Something", anchor="w", width=120)


#headings
json_tree.heading("#0", text="", anchor="w")#Columna Fantasma
json_tree.heading("Logo", text="Logo", anchor="w")
json_tree.heading("Name", text="Name", anchor="w")
json_tree.heading("Last Name", text="Last Name", anchor="w")
json_tree.heading("Something", text="Something", anchor="w")


#color rows
json_tree.tag_configure('par', background="#fff")
json_tree.tag_configure('inpar', background="#d6d6d6")
    
#Abrir y leer json para acceder a las propiedades en el objeto

with open('prueba1.json', "r") as f:
    data = json.load(f)

    count=0
    for record in data['Clientes']:
        if count % 2 ==0:
            json_tree.insert(parent='', index="end", iid=count, text="", values=(record['Logo'],record['Name'],record['Last Name'],record['Something']), tags=('par',))
        else:    
            json_tree.insert(parent='', index="end", iid=count, text="", values=(record['Logo'],record['Name'],record['Last Name'],record['Something']), tags=('inpar',))

        count+=1
   

#entrys
l1 = Label( frame_entry, text="Logo")
l1.grid(row=0, column=0)
logo_lb = Entry( frame_entry)
logo_lb.grid(row=1, column=0)

l2 = Label( frame_entry, text="Name")
l2.grid(row=0, column=1)
name_lb = Entry(frame_entry)
name_lb.grid(row=1, column=1)

l3 = Label( frame_entry, text="Last Name")
l3.grid(row=0, column=2)
lastname_lb = Entry(frame_entry)
lastname_lb.grid(row=1, column=2)

l4 = Label( frame_entry, text="Something")
l4.grid(row=0, column=3,)
something_lb = Entry(frame_entry)
something_lb.grid(row=1, column=3)

#funciones de los botones
def borrar_select():
    with open('prueba1.json', "r") as f:
        data = json.load(f)

    for record in data['Clientes']:
        borrar1 = json_tree.selection()[0]
        json_tree.delete(borrar1)

    with open('prueba1.json', "w") as f:
        json.dump(record,f,indent=4)

#Limpiar las cajas
    logo_lb.delete(0,END) 
    name_lb.delete(0,END)
    lastname_lb.delete(0,END)
    something_lb.delete(0,END)
            
borrar_btn = tk.Button(frame2, text="Delete", command=borrar_select)
borrar_btn.pack(side=RIGHT, ipadx=30, pady=10)

def select_record():
    #Limpiar las cajas
    logo_lb.delete(0,END) 
    name_lb.delete(0,END)
    lastname_lb.delete(0,END)
    something_lb.delete(0,END)

    selected = json_tree.focus() #numero de la posicion del record en el tree
    values = json_tree.item(selected,'values') #con la posicion seleccionada, toma el valor del mismo

    logo_lb.insert(0, values[0]) 
    name_lb.insert(0,values[1])
    lastname_lb.insert(0,values[2])
    something_lb.insert(0,values[3])

        
select_btn = tk.Button(frame2, text="Select", command=select_record)
select_btn.pack(side=LEFT, ipadx=30,)

ventana.mainloop()
{
  "Clientes": [
    {
      "Logo": "C:/Users/*/Desktop/Tkinter/logos/selavalacarita.png",
      "Name": "2",
      "Last Name": "3",
      "Something": "4"
    },
    {
      "Logo": "C:/Users/*/Desktop/Tkinter/logos/selavalacarita.png",
      "Name": "1",
      "Last Name": "4",
      "Something": "7"
    }
  ]
}

The below code inside borrar_select() :

    with open('prueba1.json', "r") as f:
        data = json.load(f)

    for record in data['Clientes']:
        borrar1 = json_tree.selection()[0]
        json_tree.delete(borrar1)

will loop through all records inside JSON file and try to delete first selected item in the treeview in each iteration. If there is no item selected, it will raise exception because json_tree.selection() will return empty tuple. Even there is one item selected, exception will also be raised in second iteration because the selected item has been deleted.

You can simply remove the selected items using json_tree.delete(...) and then save the remaining items to file:

# funciones de los botones
def borrar_select():
    selections = json_tree.selection()
    if selections:
        # remove selected items from treeview
        json_tree.delete(*selections)
        # get the records from treeview to as list of dictionaries
        fields = ["Logo", "Name", "Last Name", "Something"]
        records = [dict(zip(fields,json_tree.item(iid,"values"))) for iid in json_tree.get_children()]
        # save the list of dictionaris to file
        with open('prueba1.json', 'w') as f:
            json.dump({'Clientes': records}, f, indent=4)

    # Are below lines necessary?
    #Limpiar las cajas
    logo_lb.delete(0, END)
    name_lb.delete(0, END)
    lastname_lb.delete(0, END)
    something_lb.delete(0, END)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM