To provide an overview of the program, I am developing a simple retail management system. The main window of the program serves as the central hub, containing various widgets such as comboboxes, entries, and buttons. These widgets facilitate various tasks involved in managing retail operations.
In my retail management system, I heavily utilize a database to populate and update the values in my comboboxes. Currently, I have set up four comboboxes in the main window, each one related to the others. These comboboxes allow the user to select a category, sub-category, and product, in order to facilitate product management and sales tracking. The program can be viewed in its entirety by following the link provided.
Depending on the user's selection for the first combobox which represents the 'category', I want to update the second combobox (sub_cat) to show only sub-categories that belong to that particular category. For example, if the user selects "Fridge" as the category, the second combobox will show only sub-categories that are in the same row as Fridge like "Dairy", "Meat", "Fruits and Vegetables", and "Beverages".
Similarly, once the user selects an item from the second combobox, the third combobox will show only products that belong to the selected category and sub-category. At this stage, the fourth combobox can be ignored.
So far, the code for my comboboxes are as follows:
def dropdown():
# create the Combobox widget
conn = sqlite3.connect('store.db')
c = conn.cursor()
c.execute("SELECT product_name FROM raw_inventory")
product = c.fetchall()
c.execute("SELECT DISTINCT product_cat FROM raw_inventory")
cat = c.fetchall()
c.execute("SELECT DISTINCT product_subcat FROM raw_inventory")
subcat = c.fetchall()
c.execute("SELECT quantity FROM raw_inventory")
quantity = c.fetchall()
product = [item[0] for item in product]
cat = [item[0] for item in cat]
subcat = [item[0] for item in subcat]
quantity = [item[0] for item in quantity]
combobox1 = Combobox(invoice, values=cat, width=60, font=('Arial', 14))
# add the Combobox to the frame
combobox1.place(relx=0.035, rely=0.42)
combobox2 = Combobox(invoice, values=subcat, width=60, font=('Arial', 14))
# add the Combobox to the frame
combobox2.place(relx = 0.035, rely = 0.49)
combobox3 = Combobox(invoice, values=product, width=60, font=('Arial', 14))
# add the Combobox to the frame
combobox3.place(relx = 0.035, rely = 0.56)
combobox4 = Combobox(invoice, values=quantity, width=60, font=('Arial', 14))
# add the Combobox to the frame
combobox4.place(relx = 0.035, rely = 0.64)
if combobox1.get():
selected_cat = combobox1.get()
# get the subcategories for the selected category from the database
c.execute("SELECT product_subcat FROM raw_inventory WHERE product_cat=?", (selected_cat,))
subcat = c.fetchall()
subcat = list(set([item[0] for item in subcat]))
combobox2.configure(values=subcat)
else:
combobox2.configure(values=[])
dropdown()
The if statement doesnt do what I need it to do, it just messes up the whole function, however this was the only thing I tried to update the values of my comboboxes.
Just for extra info, the code for my main window:
def main_window():
# create a new window
invoice = Toplevel()
# load the image file
billimage1 = PhotoImage(file="C:/Users/.../Documents/CODE/billimage.PNG")
# create a label widget and set it as the background of the window
label2 = Label(invoice, image = billimage1)
label2.pack()
The rest is where I add all the buttons and entry boxes but I've left them out to make my queestion easier to understand.
If I understand correctly, the function dropdown()
creates the combo boxes and then immediately tries to get the selected value from one of them and update the other?
If this is the case, I think you should use a callback function for updating the other combo boxes. You can bind a function to a widget event with widget.bind(...)
. The binded function will run only after the event is emmited. For combo boxes you can use your_combobox.bind("<<ComboboxSelected>>", update_comboboxes)
, where the function update_comboboxes
will be run after selecting something from the combo box. In this function you will use one of the selected values, query the database and updates the interface.
Here is a working example where you can select a letter from the first combo box and the other one will update. Each letter has different numbers to select from.
import tkinter as tk
from tkinter import ttk
# my database
letters = ["A", "B", "C"]
numbers = {"A": [1, 2], "B": [0, 5, 10], "C": [1000, 2000]}
root = tk.Tk()
combobox_letters = ttk.Combobox(root, values=letters)
combobox_letters.pack()
combobox_numbers = ttk.Combobox(root)
combobox_numbers.pack()
def update_combobox(event: "tk.Event[ttk.Combobox]"):
# this will run after user selects something from the letter combobox
selected_letter = event.widget.get()
available_numbers = numbers[selected_letter]
combobox_numbers.config(values=available_numbers)
# bind function update_combobox to combobox selection event
combobox_letters.bind("<<ComboboxSelected>>", update_combobox)
root.mainloop()