#more code above
Traceback (most recent call last):
File “C:Program FilesPython312Libtkinter_init_.py”, line 1962, in call
return self.func(*args)
^^^^^^^^^^^^^^^^
File “C:UsersMawahOneDrive123.py”, line 470, in save_data
self.db.insert_item(item, size_numeric, size, year, price, condition)
File “C:UsersMawahOneDrive123.py”, line 300, in insert_item
self.cur.execute(”’INSERT INTO items (Item, SizeNumeric, Size, Year, Price, Condition, IsSold)
sqlite3.OperationalError: table items has no column named IsSold
class Database:
def __init__(self):
self.conn = sqlite3.connect("items.db")
self.cur = self.conn.cursor()
self.create_table()
def create_table(self):
# Check if the table already exists
self.cur.execute('''SELECT count(name) FROM sqlite_master WHERE type='table' AND name='items' ''')
if self.cur.fetchone()[0] == 0:
# Table doesn't exist, create it along with the IsSold column
self.cur.execute('''CREATE TABLE IF NOT EXISTS items (
ItemId INTEGER PRIMARY KEY,
Item TEXT,
SizeNumeric TEXT,
Size TEXT,
Year TEXT,
Price REAL,
Condition TEXT,
IsSold INTEGER )''')
self.conn.commit()
def insert_item(self, item, size_numeric, size, year, price, condition):
# SQL query to insert an item into the table
self.cur.execute('''INSERT INTO items (Item, SizeNumeric, Size, Year, Price, Condition, IsSold)
VALUES (?, ?, ?, ?, ?, ?, ?)''', (item, size_numeric, size, year, price, condition, 0))
self.conn.commit()
def close(self):
self.conn.close()
class Add_Item:
def __init__(self, master):
self.master = master
master.geometry('600x600')
master.title("Add Item")
master.configure(bg="#A7C7E7")
self.lblItem = tk.Label(master, text="Item", width=20, font=("Cambria", 10), bg="#A7C7E7")
self.lblItem.place(x=80, y=130)
self.ddlItem = ttk.Combobox(master, values=["Tie", "Blazer", "Trousers", "Polos", "Jumpers"], state="readonly")
self.ddlItem.place(x=240, y=130)
self.ddlItem.bind("<<ComboboxSelected>>", self.show_fields)
# Initialize all fields
self.lblYear = tk.Label(master, text="Year", width=20, font=("Cambria", 10), bg="#A7C7E7")
self.ddlYear = ttk.Combobox(master, values=["yr7", "yr8", "yr9", "yr10", "yr11"], state="readonly")
self.lblSizeNumeric = tk.Label(master, text="Size (Numeric)", width=20, font=("Cambria", 10), bg="#A7C7E7")
self.ddlSizeNumeric = ttk.Combobox(master, values=["11", "13", "14", "15", "16", "17", "18", "19"], state="readonly")
self.lblSize = tk.Label(master, text="Size", width=20, font=("Cambria", 10), bg="#A7C7E7")
self.ddlSize = ttk.Combobox(master, values=["S", "M", "L", "XL"], state="readonly")
self.lblCondition = tk.Label(master, text="Condition", width=20, font=("Cambria", 10), bg="#A7C7E7")
self.ddlCondition = ttk.Combobox(master, values=["Good", "Bad"], state="readonly")
self.lblPrice = tk.Label(master, text="Price", width=20, font=("Cambria", 10), bg="#A7C7E7")
self.entPrice = tk.Entry(master)
self.btnGoBack = tk.Button(master, text="u2190", font=("Cambria", 20), bg="#A7C7E7", fg="black", command=self.go_back)
self.btnGoBack.place(x=20, y=20)
# added btnSave button
self.btnSave = tk.Button(master, text="Save", font=("Cambria", 17), bg="#A7C7E7", fg="black", command=self.save_data)
self.btnSave.place(x=250, y=280) # Adjust position as needed
self.db = Database() # Create an instance of the Database class
# Initially hide all fields
self.hide_all_fields()
def show_fields(self, event=None):
selected_item = self.ddlItem.get()
self.hide_all_fields() # Hide all fields first
if selected_item == "Tie":
self.show_tie_fields()
elif selected_item == "Blazer":
self.show_blazer_fields()
elif selected_item == "Trousers":
self.show_trousers_fields()
elif selected_item == "Polos":
self.show_polos_fields()
elif selected_item == "Jumpers":
self.show_jumpers_fields()
def show_tie_fields(self):
# Show Tie related fields
self.lblYear.place(x=80, y=160)
self.ddlYear.place(x=240, y=160)
self.lblCondition.place(x=80, y=190)
self.ddlCondition.place(x=240, y=190)
self.lblPrice.place(x=80, y=220)
self.entPrice.place(x=240, y=220)
def show_blazer_fields(self):
# Show Blazer related fields
self.lblSize.place(x=80, y=160)
self.ddlSize.place(x=240, y=160)
self.lblCondition.place(x=80, y=190)
self.ddlCondition.place(x=240, y=190)
self.lblPrice.place(x=80, y=220)
self.entPrice.place(x=240, y=220)
def show_trousers_fields(self):
# Show Trousers related fields
self.lblSizeNumeric.place(x=80, y=160)
self.ddlSizeNumeric.place(x=240, y=160)
self.lblCondition.place(x=80, y=190)
self.ddlCondition.place(x=240, y=190)
self.lblPrice.place(x=80, y=220)
self.entPrice.place(x=240, y=220)
def show_polos_fields(self):
# Show Polos related fields
self.lblSize.place(x=80, y=160)
self.ddlSize.place(x=240, y=160)
self.lblCondition.place(x=80, y=190)
self.ddlCondition.place(x=240, y=190)
self.lblPrice.place(x=80, y=220)
self.entPrice.place(x=240, y=220)
def show_jumpers_fields(self):
# Show Jumpers related fields
self.lblSize.place(x=80, y=160)
self.ddlSize.place(x=240, y=160)
self.lblCondition.place(x=80, y=190)
self.ddlCondition.place(x=240, y=190)
self.lblPrice.place(x=80, y=220)
self.entPrice.place(x=240, y=220)
def hide_all_fields(self):
# Hide all fields
self.lblYear.place_forget()
self.ddlYear.place_forget()
self.lblSizeNumeric.place_forget
self.ddlSizeNumeric.place_forget()
self.lblSize.place_forget()
self.ddlSize.place_forget()
self.lblCondition.place_forget()
self.ddlCondition.place_forget()
self.lblPrice.place_forget()
self.entPrice.place_forget()
self.ddlSizeNumeric.place_forget()
self.lblSize.place_forget()
self.ddlSize.place_forget()
self.lblCondition.place_forget()
self.ddlCondition.place_forget()
self.lblPrice.place_forget()
self.entPrice.place_forget()
def go_back(self):
self.db.close()# Close the database connection
self.master.destroy() # Close the current window when "Go Back" button is clicked
def save_data(self):#this is the block of code that the syntax error occurs
# Fetching values from the widgets
item = self.ddlItem.get()
year = self.ddlYear.get()
size_numeric = self.ddlSizeNumeric.get()
size = self.ddlSize.get()
condition = self.ddlCondition.get()
price = self.entPrice.get()
# Check if any of the required fields are empty based on the selected item
if item == "Tie" and not all([year, condition, price]):
messagebox.showerror("Error", "Data invalid: missing field")
return
elif item == "Blazer" and not all([size, condition, price]):
messagebox.showerror("Error", "Data invalid: missing field")
return
elif item == "Trousers" and not all([size_numeric, condition, price]):
messagebox.showerror("Error", "Data invalid: missing field")
return
elif item == "Polos" and not all([size, condition, price]):
messagebox.showerror("Error", "Data invalid: missing field")
return
elif item == "Jumpers" and not all([size, condition, price]):
messagebox.showerror("Error", "Data invalid: missing field")
return
# Check if price is a valid float and below or equal to £30.00
try:
price_float = float(price)
if price_float > 30.00:
raise ValueError("Price is above the limit (£30.00)")
except ValueError as e:
error_message = str(e)
messagebox.showerror("Error", error_message + "nPlease enter a valid price")
return
# Insert data into the database
self.db.insert_item(item, size_numeric, size, year, price, condition)
# Close the current window
self.master.destroy()
class BuyItemPage:
def __init__(self, master):
self.master = master
master.title("Buy Item")
master.configure(bg="#A7C7E7")
# Set the initial size of the window
master.geometry("600x600")
# Create a Treeview widget
self.create_treeview()
# Create a search entry field and button
self.create_search_widgets()
# Fetch items from the database and insert them into the Treeview
self.populate_treeview()
# Add a Back button
self.create_back_button()
def create_back_button(self):
# Create a Back button to return to the original page
self.back_button = tk.Button(self.master, text="Back to Main menu", font=("Cambria", 12), bg="#A7C7E7", fg="white", command=self.back_to_categories)
self.back_button.pack(side=tk.BOTTOM, pady=10)
def back_to_categories(self):
# Destroy the current window and return to the main page
self.master.destroy()
# Other methods remain the same...
def create_treeview(self):
# Create a Treeview widget
self.treeview = ttk.Treeview(self.master)
# Add columns
self.treeview['columns'] = ('Item ID', 'Item', 'SizeNumeric', 'Size', 'Year', 'Price', 'Condition', 'Sold')
# Define column headings
self.treeview.heading('Item ID', text='Item ID', anchor=tk.CENTER)
self.treeview.heading('Item', text='Item', anchor=tk.CENTER)
self.treeview.heading('SizeNumeric', text='SizeNumeric', anchor=tk.CENTER)
self.treeview.heading('Size', text='Size', anchor=tk.CENTER)
self.treeview.heading('Year', text='Year', anchor=tk.CENTER)
self.treeview.heading('Price', text='Price', anchor=tk.CENTER)
self.treeview.heading('Condition', text='Condition', anchor=tk.CENTER)
self.treeview.heading('Sold', text='Sold', anchor=tk.CENTER)
# Pack the Treeview
self.treeview.pack(expand=True, fill='both')
# Bind double click event to the Treeview
self.treeview.bind("<Double-1>", self.on_item_double_click)
def create_search_widgets(self):
# Create search entry field and button
self.search_var = tk.StringVar()
self.search_entry = tk.Entry(self.master, textvariable=self.search_var, font=("Cambria", 12))
self.search_entry.pack(side=tk.TOP, padx=10, pady=5, fill=tk.X)
self.search_button = tk.Button(self.master, text="Search", font=("Cambria", 12), bg="#A7C7E7", fg="white", command=self.search_items)
self.search_button.pack(side=tk.TOP, padx=10, pady=1)
def populate_treeview(self):
# Connect to the database
conn = sqlite3.connect("items.db")
cursor = conn.cursor()
# Fetch non-empty categories from the database
cursor.execute("SELECT DISTINCT(Item) FROM items WHERE Item IS NOT NULL AND Item != ''")
categories = cursor.fetchall()
# Clear existing items from the Treeview
self.treeview.delete(*self.treeview.get_children())
# Iterate through each category
for category in categories:
category_name = category[0]
# Insert category as parent item
parent_item = self.treeview.insert('', 'end', text=category_name)
# Fetch items belonging to the current category
cursor.execute("SELECT * FROM items WHERE Item=?", (category_name,))
items = cursor.fetchall()
# Populate the Treeview with items belonging to the current category
for item in items:
self.treeview.insert(parent_item, 'end', values=item)
# Close the database connection
conn.close()
def search_items(self):
# Get the search query from the entry field
query = self.search_var.get()
# Connect to the database
conn = sqlite3.connect("items.db")
cursor = conn.cursor()
# Search for items based on the query
cursor.execute("SELECT * FROM items WHERE Item LIKE ? OR SizeNumeric LIKE ? OR Size LIKE ? OR Year LIKE ? OR Price LIKE ? OR Condition LIKE ?", ('%' + query + '%', '%' + query + '%', '%' + query + '%', '%' + query + '%', '%' + query + '%', '%' + query + '%'))
search_results = cursor.fetchall()
# Close the database connection
conn.close()
# Clear existing items from the Treeview
self.treeview.delete(*self.treeview.get_children())
# Populate the Treeview with search results
for item in search_results:
self.treeview.insert('', 'end', values=item)
def on_item_double_click(self, event):
selected_item = self.treeview.selection()[0]
# Retrieve Item ID from the selected item
item_id = self.treeview.item(selected_item)['values'][0]
# Retrieve the item name for displaying in the messagebox
item_name = self.treeview.item(selected_item)['values'][1]
# Display a messagebox confirmation
response = messagebox.askyesno("Buy Now", "Do you want to buy {item_name}?")
if response: # If the user clicks "Yes"
self.mark_as_sold(item_id) # Mark the item as sold and remove it from the Treeview
def mark_as_sold(self, item_id):
# Update the Treeview to reflect the change
selected_item = self.treeview.selection()[0]
self.treeview.set(selected_item, column='Sold', value='Yes')
# Remove the item from the Treeview
self.treeview.delete(selected_item)
class MainMenu:
def __init__(self, master):
self.master = master
# Initialization...
master.title("Unisell Main Menu")
master.configure(bg="white")
# Set the initial size of the window
master.geometry("800x600") # Adjust the size as needed
# Logo
logo_label = tk.Label(master, text="Unisell",bg="white",fg="#0047AB", font=("Cambria", 30, "bold"))
logo_label.pack(pady=10)
# Log Out Button
logout_button = tk.Button(master, text="Log Out", font=("Cambria", 12), bg="white", fg="black", command=self.logout)
logout_button.pack(side=tk.TOP, anchor=tk.NW, padx=10, pady=1)
# Footer Menu
self.create_footer_menu()
def create_footer_menu(self):
footer_frame = tk.Frame(self.master, bg="white") # Set background color to white
footer_frame.pack(side=tk.BOTTOM, fill=tk.X) # Place the footer at the bottom and make it fill horizontally
Add_item_button = tk.Button(footer_frame, text="Add item", width=20, height=7,pady=15, font=("Cambria", 20), bg="#A7C7E7", fg="white", command=self.show_add_item_window)
buy_item_button = tk.Button(footer_frame, text="Buy item", width=20, height=7, pady=15, font=("Cambria", 20), bg="#A7C7E7", fg="white", command=self.show_buy_item_window)
Add_item_button.pack(side=tk.LEFT, expand=True, pady=5)
buy_item_button.pack(side=tk.LEFT, expand=True, pady=5)
def show_add_item_window(self):
add_item_window = tk.Toplevel(self.master)
add_item_window.title("Add Item window")
add_item_window.geometry("600x600")
# Create an instance of the Add_Item class within the Toplevel window
add_item_form = Add_Item(add_item_window)
def show_buy_item_window(self):
buy_item_window = tk.Toplevel(self.master)
buy_item_window.title("Buy Item window")
buy_item_window.geometry("600x600")
# Create an instance of the BuyItemPage class within the Toplevel window
buy_item_page = BuyItemPage(buy_item_window)
def logout(self):
self.master.destroy() # Close the main menu window when logging out
def main():
root = tk.Tk()
app = LoginPage(root)
root.mainloop()
if __name__ == '__main__':
main()