Home > Back-end >  Combobox combined from database: tkinter.TclError: Index 0 out of range and other error
Combobox combined from database: tkinter.TclError: Index 0 out of range and other error

Time:09-17

I'm trying to create a simple combined combobox that pulls the data from the database Sqlite and Python 3.x. If I open the combobox1 "Nation/Country", as an example, I would like to display the relative cities in the cobobox2 "City".

I get this error

     return self.tk.call (self._w, "current", newindex)
_tkinter.TclError: Index 0 out of range

Even not getting it previously, the combo combobox didn't work well, because if i open England and receive London, Liverpool, Manchester, etc and i select other countries in the combobox1 "Nation/Country", I will always receive the cities of England. For example, I open France and still receive London, Liverpool, Manchester (not Paris, Marseille, Bordeaux, etc).

How can I solve? Can you show me the answer with my code please? I'm new to Python, if you only theoretically explain the problem to me I might not understand. Thanks

#combobox nation
lbl_Nation = Label(root, text="City", font=("Calibri", 11), bg="#a8dd71", fg="white")
lbl_Nation.place(x=6, y=60)

combo_Nation = ttk.Combobox(root, font=("Calibri", 11), width=30, state="readonly")
combo_Nation.place(x=180, y=60)
combo_Nation.set("Select Nation")

def combo_nation():
    cursor.execute('SELECT Nation FROM All_Nation')
    result=[row[0] for row in cursor]
    return result

combo_Nation['value'] = combo_nation()
combo_Nation.set("Seleziona")

############################################################### 
#combobox city
lbl_City = Label(root, text="City", font=("Calibri", 11), bg="white", fg="black")
lbl_City.place(x=6, y=110)

combo_City = ttk.Combobox(root, font=("Calibri", 11), width=30, state="readonly")
combo_City.place(x=180, y=110)
combo_City.set("Select City")

def combo_city():
    val = combo_City.get()
    cursor.execute('SELECT s.City FROM All_Nation s, All_Nation c WHERE s.ID_Nation=c.ID_Nation AND c.City = ?', (val,))
    result=[row[0] for row in cursor]
    combo_City['value'] = result
    combo_City.current(0)
    return result

combo_City['value'] = combo_City()
combo_City.set("Select")


combo_Nation.bind('<<ComboboxSelected>>', combo_city)

UPDATE N.1

CREATE TABLE "All_Nation" (
    "ID_Nation" INTEGER,
    "Nation"    TEXT,
    PRIMARY KEY("ID_Nation" AUTOINCREMENT)
);

CREATE TABLE "CITY" (
    "ID_City"   INTEGER,
    "City"  TEXT,
    "ID_Nation" INTEGER,
    FOREIGN KEY("ID_Nation") REFERENCES "All_Nation"("ID_Nation") ON DELETE NO ACTION ON UPDATE NO ACTION,
    PRIMARY KEY("ID_Sq" AUTOINCREMENT)
);

CodePudding user response:

Based on provided table information, the SQL used inside combo_city() will returns no record.

Below is an example code based on posted one:

import tkinter as tk
from tkinter import ttk
import sqlite3

cnx = sqlite3.connect('nations.db')
cursor = cnx.cursor()

def combo_nation():
    cursor.execute('SELECT Nation FROM All_Nation')
    result = [row[0] for row in cursor]
    return result

def combo_city(event):
    nation = combo_Nation.get() # get the selected nation
    cursor.execute('SELECT City FROM All_Nation n, CITY c WHERE n.ID_Nation = c.ID_Nation AND n.Nation = ?', (nation,))
    result = [row[0] for row in cursor]
    combo_City['values'] = result
    combo_City.set('Select City')

root = tk.Tk()
root.geometry('600x400')
root.config(bg='white')

# Nation
tk.Label(root, text="Nation/Country", font=("Calibri", 11), bg="white", fg="black").place(x=6, y=60)

combo_Nation = ttk.Combobox(root, font=("Calibri", 11), width=30, state="readonly")
combo_Nation.place(x=180, y=60)
combo_Nation.set("Select Nation")

combo_Nation['values'] = combo_nation()
combo_Nation.set("Seleziona")
combo_Nation.bind('<<ComboboxSelected>>', combo_city)

# City
tk.Label(root, text="City", font=("Calibri", 11), bg="white", fg="black").place(x=6, y=110)

combo_City = ttk.Combobox(root, font=("Calibri", 11), width=30, state="readonly")
combo_City.place(x=180, y=110)
combo_City.set("Select City")

root.mainloop()
  • Related