I am connecting frontend to backend of a database application using Tkinter and sqlite3.
Need help finding potential reasons that resulted in this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Peng\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "frontend.py", line 9, in get_selected_row
index=list1.curselection()[0]
IndexError: tuple index out of range
But list1.curselection()[0]
is just the id
, why is it out of range?
Any help on finding where went wrong will be greatly appreciated!!!
My code:
frontend.py:
from tkinter import *
import backend
window=Tk()
list1.bind('<<ListboxSelect>>',get_selected_row)
def update_command():
backend.update(selected_tuple[0],title_text.get(),author_text.get(),year_text.get(),isbn_text.get())
def get_selected_row(event):
global selected_tuple
index=list1.curselection()[0]
selected_tuple=list1.get(index)
e1.delete(0,END)
e1.insert(END,selected_tuple[1])
e2.delete(0,END)
e2.insert(END,selected_tuple[2])
e3.delete(0,END)
e3.insert(END,selected_tuple[3])
e4.delete(0,END)
e4.insert(END,selected_tuple[4])
backend.py:
import sqlite3
def update(id,title,author,year,isbn):
conn=sqlite3.connect("books.db")
cur=conn.cursor()
cur.execute("UPDATE book SET title=?,author=?,year=?,isbn=? WHERE id=?",(title,author,year,isbn,id))
conn.commit()
conn.close()
Your method is being triggered when there is nothing selected. The easiest fix is to simply check if the tuple is empty:
def get_selected_row(event):
global selected_tuple
index=list1.curselection()
if index: # if the tuple is not empty
selected_tuple=list1.get(index[0])
e1.delete(0,END)
e1.insert(END,selected_tuple[1])
e2.delete(0,END)
e2.insert(END,selected_tuple[2])
e3.delete(0,END)
e3.insert(END,selected_tuple[3])
e4.delete(0,END)
e4.insert(END,selected_tuple[4])
A more proper fix is to find out when it's being triggered like that and prevent it.
it happens when you click into the list1 while it is empty this is the line that triggers it
list1.bind('<<ListboxSelect>>',get_selected_row)
the solution mentioned above is suitable since you don't seem to have any other code manipulating this event however, i would word the solution a bit differently, to be consistent with your code naming conventions:
def get_selected_row(event):
global selected_tuple
if list1.curselection():
index=list1.curselection()[0]
selected_tuple=list1.get(index)
e1.delete(0,END)
e1.insert(END,selected_tuple[1])
e2.delete(0,END)
e2.insert(END,selected_tuple[2])
e3.delete(0,END)
e3.insert(END,selected_tuple[3])
e4.delete(0,END)
e4.insert(END,selected_tuple[4])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With