I have 2 comboboxes. Selection from first is supposed to trigger the second to populate. The first is populated from a sqlite3 database and it works just fine but the trigger for the second does not work even though it is grabbing the correct information. I am NOT getting any ERRORs. My print statement to the output confirms this. but for some reason that information is not getting into the second box. I have tried for days to figure it out and have started validating the definition of insanity. Doing the same thing over and over and expecting a different result. I have read the documentation and have searched the web but I have not found a solution. Here is the code that I have written:
from tkinter import *
from tkcalendar import Calendar, DateEntry
from tkinter import ttk
import tkinter.messagebox
import sqlite3
class work:
def __init__(self, root):
self.root = root
self.root.title("Service Ticket")
self.root.iconbitmap('Securitas.ico')
WIDTH=1024
HEIGHT=768
# center the form to the user's screen
sc_width = self.root.winfo_screenwidth()
sc_height = self.root.winfo_screenheight()
x_coordinate = (sc_width/2)-(WIDTH/2)
y_coordinate = (sc_height/2)-(HEIGHT/2)
self.root.geometry("%dx%d+%d+%d"%(WIDTH, HEIGHT, x_coordinate, y_coordinate))
MainFrame = Frame(self.root, bd=10, width = WIDTH, height=HEIGHT, relief=RIDGE)
MainFrame.place(relwidth=1, relheight=1)
frame1 = Frame(MainFrame, highlightbackground='sky blue', highlightcolor='sky blue', highlightthickness=2
frame1.place(relx=0.5, relwidth=1, relheight=0.435, anchor='n')
frame2 = Frame(MainFrame, highlightbackground='sky blue', highlightcolor='sky blue', highlightthickness=2) # Buttons
frame2['relief'] = 'ridge'
frame2.place(relx=0.5, rely=0.44, relwidth=0.95, relheight=0.075, anchor='n')
frame3 = Frame(MainFrame, highlightbackground='sky blue', highlightcolor='sky blue', highlightthickness=2) # DataGrid
frame3['relief'] = 'ridge'
frame3.place(relx=0.5, rely=0.52, relwidth=0.95, relheight=0.3, anchor='n')
def connect_db():
conn = sqlite3.connect("service.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS ticket (id INTEGER PRIMARY KEY, date TEXT, tr TEXT, wo TEXT, cust TEXT, addr TEXT, misc TEXT, issue TEXT, notes TEXT)")
conn.commit()
conn.close()
def iExit():
iExit = tkinter.messagebox.askyesno("Service Ticket", "Confirm that you want to Exit")
if iExit > 0:
root.destroy()
return
def Reset():
self.txtTR.delete(0, END)
self.txtWO.delete(0, END)
self.cboCust.delete(0, END)
self.cboAddr.delete(0, END)
self.txtMisc.delete(0, END)
self.txtIssue.delete(0, END)
self.txtNotes.delete("1.0", END)
def fill_verify():
if(len(self.txtTR.get()) !=0):
pass
else:
tkinter.messagebox.showwarning('', "The TR number must be entered")
self.txtTR.focus()
if(len(self.cboCust.get()) !=0):
pass
else:
tkinter.messagebox.showwarning('', "Must have a Customer Selected")
self.cboCust.focus()
if(len(self.cboAddr.get()) !=0):
pass
else:
tkinter.messagebox.showwarning('', "Must have a Customer's Address Selected")
self.cboAddr.focus()
if(len(self.txtIssue.get()) !=0):
pass
else:
tkinter.messagebox.showwarning('', "There must be an Issue entered")
self.txtIssue.focus()
if(len(self.txtNotes.get("1.0", END)) !=0):
pass
else:
tkinter.messagebox.showwarning('', "There must be Notes entered")
self.txtNotes.focus()
def SaveRec():
fill_verify()
conn = sqlite3.connect("service.db")
cur = conn.cursor()
cur.execute("INSERT INTO ticket VALUES(NULL,?,?,?,?,?,?,?,?)", (
self.txtCal.get(), self.txtTR.get(), self.txtWO.get(), self.cboCust.get(), self.cboAddr.get(),
self.txtMisc.get(), self.txtIssue.get(), self.txtNotes.get('1.0', END)))
conn.commit()
DisplayData()
conn.close()
def DisplayData():
conn = sqlite3.connect("service.db")
cur = conn.cursor()
cur.execute("SELECT * FROM ticket")
result = cur.fetchall()
if len(result) !=0:
self.tree1.delete(*self.tree1.get_children())
for row in result:
self.tree1.insert('', END, values=row)
conn.commit()
conn.close()
def UpdateRec():
conn = sqlite3.connect("service.db")
cur = conn.cursor()
cur.execute("UPDATE ticket SET date=?, tr=?, wo=?, cust=?, addr=?, misc=?, issue=?, notes=? WHERE id=?", \
(self.txtCal.get(), self.txtTR.get(), self.txtWO.get(), self.cboCust.get(), self.cboAddr.get(),
self.txtMisc.get(), self.txtIssue.get(), self.txtNotes.get('1.0', END), rec_id,))
conn.commit()
conn.close()
DisplayData()
def RecSelected(ev):
Reset()
viewInfo = self.tree1.focus()
selected_data = self.tree1.item(viewInfo)
row = selected_data['values']
global rec_id
self.txtCal.delete(0, END) # this is a tkcalender DateEntry Box and it doesn't use the set method
self.txtCal.insert(0, row[1]) # but it does use some of the same methods as a standard Entry box
self.txtTR.insert(0, row[2])
self.txtWO.insert(0, row[3])
self.cboCust.insert(0, row[4])
self.cboAddr.insert(0, row[5])
self.txtMisc.insert(0, row[6])
self.txtIssue.insert(0, row[7])
self.txtNotes.insert(END, (row[8])) # this is a multi line Text box and it doesn't use the set method
rec_id = format(row[0]) # must be formatted to a string so the update function can use it
self.tree1.selection_set('')
def fill_custbox(): # THIS WORKS
conn = sqlite3.connect("service.db")
cur = conn.cursor()
cur.execute("SELECT DISTINCT cust FROM ticket Order BY cust")
data = []
for row in cur.fetchall():
data.append(row[0])
return data
conn.commit()
conn.close()
def fill_addrbox(): # THIS DOES NOT WORK
conn = sqlite3.connect("service.db")
cur = conn.cursor()
cur.execute("SELECT distinct addr FROM ticket WHERE cust = '%s'" % (self.cboCust.get(),))
self.cboAddr.delete(0, END)
data = []
for row in cur.fetchall():
data.append(row[0])
#self.cboAddr.insert('', row[0],)
print(row)
return data
conn.commit()
conn.close()
self.lblDate = Label(frame1, text="Date: ", font=40)
self.lblDate.place(relwidth=0.1, relheight=0.125)
self.lblTR = Label(frame1, text="TR #: ", font=40)
self.lblTR.place(relx=0.2, relwidth=0.1, relheight=0.125)
self.lblWO = Label(frame1, text="WO/PO: ", font=40)
self.lblWO.place(relx=0.6, relwidth=0.1, relheight=0.125)
self.txtCal = DateEntry(frame1, font=40, year=2021)
self.txtCal.place(relx=0.025, rely=0.12, relwidth=0.1, relheight=0.125)
self.txtTR = Entry(frame1, font=40)
self.txtTR.place(relx=0.23, rely=0.12, relwidth=0.3, relheight=0.125)
self.txtWO = Entry(frame1, font=40)
self.txtWO.place(relx=0.62, rely=0.12, relwidth=0.355, relheight=0.125)
self.lblCust = Label(frame1, text="Customer: ", font=40)
self.lblCust.place(rely=0.24, relwidth=0.13, relheight=0.125)
self.lblAddr = Label(frame1, text="Address: ", font=40)
self.lblAddr.place(relx=0.485, rely=0.24, relwidth=0.1, relheight=0.125)
self.cboCust = ttk.Combobox(frame1, font=40)
self.cboCust.place(relx=0.025, rely=0.36, relwidth=0.425, relheight=0.125)
self.cboAddr = ttk.Combobox(frame1, font=40, postcommand=fill_addrbox)
self.cboAddr.place(relx=0.5, rely=0.36, relwidth=0.475, relheight=0.125)
self.cboCust['values'] = (fill_custbox())
self.cboCust.bind('<<ComboboxSelected>>', fill_addrbox)
self.cboAddr['values'] = (fill_addrbox())
self.lblMisc = Label(frame1, text="Misc: ", font=40)
self.lblMisc.place(relwidth=0.1, rely=0.49, relheight=0.12)
self.lblIssue = Label(frame1, text="Issue: ", font=40)
self.lblIssue.place(relx=0.475, rely=0.49, relwidth=0.1, relheight=0.12)
self.txtMisc = Entry(frame1, font=40)
self.txtMisc.place(relx=0.025, rely=0.6, relwidth=0.425, relheight=0.125)
self.txtIssue = Entry(frame1, font=40)
self.txtIssue.place(relx=0.5, rely=0.6, relwidth=0.475, relheight=0.125)
self.lblNotes = Label(frame1, text="Notes: ", font=40)
self.lblNotes.place(rely=0.73, relwidth=0.1, relheight=0.125)
self.txtNotes = Text(frame1, font=40)
self.txtNotes.place(relx=0.025, rely=0.84, relwidth=0.95, relheight=0.125)
#=====frame2 Button widgets============================
self.btn_save = Button(frame2, text="SAVE", font=40, bd=2, command=SaveRec)
self.btn_save.place(relx=0.03, rely=0.1, relwidth=0.1, relheight=0.8)
self.btn_update = Button(frame2, text="UPDATE", font=40, bd=2, command=UpdateRec)
self.btn_update.place(relx=0.14, rely=0.1, relwidth=0.1, relheight=0.8)
self.btn_reset = Button(frame2, text="RESET", font=40, bd=2, command=Reset)
self.btn_reset.place(relx=0.25, rely=0.1, relwidth=0.1, relheight=0.8)
self.btn_delete = Button(frame2, text="DELETE", font=40, bd=2)
self.btn_delete.place(relx=0.36, rely=0.1, relwidth=0.1, relheight=0.8)
self.btn_exit = Button(frame2, text="EXIT", font=40, bd=2,command=iExit)
self.btn_exit.place(relx=0.47, rely=0.1, relwidth=0.1, relheight=0.8)
self.btn_parts = Button(frame2, text="PARTS USED ", font=40)
self.btn_parts.place(relx=0.84, rely=0.1, relwidth=0.13, relheight=0.8)
#=====frame3 Treeview widget============================
scroll_y = Scrollbar(frame3, orient=VERTICAL)
self.tree1 = ttk.Treeview(frame3, yscrollcommand=scroll_y.set,
columns=("ID","Date", "TR", "WO", "Cust", "Addr", "Misc", "Issue", "Notes"))
scroll_y.pack(side=RIGHT, fill=Y)
self.tree1.heading("ID", text="ID", anchor=W)
self.tree1.heading("Date", text="Date", anchor=W)
self.tree1.heading("TR", text="TR #", anchor=W)
self.tree1.heading("WO", text="WO/PO #", anchor=W)
self.tree1.heading("Cust", text="Cust", anchor=W)
self.tree1.heading("Addr", text="Addr", anchor=W)
self.tree1.heading("Misc", text="Misc", anchor=W)
self.tree1.heading("Issue", text="Issue", anchor=W)
self.tree1.heading("Notes", text="Notes", anchor=W)
self.tree1['show'] = 'headings'
self.tree1.column("ID", width=30)
self.tree1.column("Date", width=50)
self.tree1.column("TR", width=50)
self.tree1.column("WO", width=50)
self.tree1.column("Cust", width=100)
self.tree1.column("Addr", width=100)
self.tree1.column("Misc", width=75)
self.tree1.column("Issue", width=100)
self.tree1.column("Notes", width=200)
self.tree1.pack(fill=BOTH, expand=1)
self.tree1.bind("<ButtonRelease-1>", RecSelected)
connect_db()
DisplayData()
if __name__=='__main__':
root = Tk()
application = work(root)
root.mainloop()
