tiberhockey
tiberhockey

Reputation: 576

Tkinter Listbox : Botton delete the selected Items from the Listbox and JSON files

so I have a ListBox on my Tkinter menu, the items on the Listbox are my user.json list-Dict (Code below)

The question is: How can i create a button that delete the Listbox selected items from my JSON list.

I already know the code to delete the Item from the Listbox which is: lb.delete(ANCHOR), but i searched a lot how to delete the selected listbox dicts from my JSON list/dicts which I did not find any result.Thank you for the Help.

My LISTBOX:

#LISTBOX

lb = Listbox(tab2, width=40, height=16)
lb.grid(row=0, column=1)
lb.insert(END, "CLIENTS")

for person in data["person"]:
    ans1 = (f"Name: {person['name']}")
    ans2 = (f" City: {person['City']}")
    ans3 = (f" Gender: {person['Gender']}")
    ans = "\n" + ans1 + "\n" + ans2 + "\n" + ans3 + "\n"
    lb.insert(END, ans)

MY FUNCTION AND BUTTON

def delt():
    lb.delete(ANCHOR)

Button(tab2, text="DEL", command=delt).grid(row=4, column=1)

MY JSON FILE

{
  "person": [
    {
      "Name": "Peter",
      "City": "Montreal",
      "Gender": "Male"
    },
    {
      "Name": "Alex",
      "City": "Laval",
      "Gender": "Male"
    },
    {
      "Name": "Annie",
      "City": "Quebec",
      "Gender": "Female"
    }
  ]
}

Upvotes: 0

Views: 766

Answers (1)

Somraj Chowdhury
Somraj Chowdhury

Reputation: 1043

Since in the json file, the person key is a list of dictionaries, therefore our main task is to convert the row selected in the listbox to a dictionary and then remove that dictionary from the person key and write the changes to the json file.

user.json file

{
  "person": [
    {
      "Name": "Peter",
      "City": "Montreal",
      "Gender": "Male"
    },
    {
      "Name": "Alex",
      "City": "Laval",
      "Gender": "Male"
    },
    {
      "Name": "Annie",
      "City": "Quebec",
      "Gender": "Female"
    }
  ]
}

Code:

import tkinter as tk
import json

window = tk.Tk()

# selectmode='single' says that you can select only one row at a time in the listbox
lb = tk.Listbox(window, width=40, height=16, selectmode='single')
lb.grid(row=0, column=1)
lb.insert('end', "CLIENTS")

# open and load your user.json file
with open('user.json', 'r') as json_file:
    data = json.load(json_file)

for person in data['person']:
    ans1 = person['Name']
    ans2 = person['City']
    ans3 = person['Gender']
    ans = "\n" + "Name: " + ans1 + " \n" + "City: " + ans2 + " \n" + "Gender: " + ans3 + "\n"
    lb.insert('end', ans)

msg_label = tk.Label(window)
msg_label.grid(row=5, column=1)

def delt():
    with open('user.json', 'r') as json_file:
        data = json.load(json_file)

    # get the values that is under selection in list box
    # it returns one long string in the format you inserted the data in the list box (see above-> ans)
    row_values = lb.get(tk.ACTIVE)

    # split the results into a list of words and replace ':' in 'Name:', 'City:' and 'Gender: ' with ''
    row_values = [row_value.replace(':', '') for row_value in row_values.split()]

    # in each list box row,
    # every even index can be thought as keys of a dictionary
    keys = row_values[0::2]
    # every odd index can be thought as values of a dictionary
    values = row_values[1::2]

    # using the keys and values lists, convert the row data into a dict
    # that matches the format of data in your .json file
    row_selection = dict()
    for key, value in zip(keys, values):
        row_selection[key] = value

    # remove the entry from your user.json file
    # if that entry is found in the file
    if row_selection in data['person']:
        data['person'].remove(row_selection)

        # write changes to file
        with open('user.json', 'w') as json_file:
            data = json.dump(data, json_file)

        # delete the entry from listbox    
        lb.delete(tk.ANCHOR)

        msg_label.config(text='Row removed from file')
    else:
        msg_label.config(text='Row not found in the file')

delete_btn = tk.Button(window, text="DEL", command=delt)
delete_btn.grid(row=4, column=1)


I have tried to explain every line with a comment. Hope you understand my explanation. Try printing every variable in the delt() function to have clarity.

Upvotes: 2

Related Questions