Complete tasks 40 and 41
This commit is contained in:
parent
bad7599442
commit
3439af955c
BIN
40 Simple GUI Quiz/eiffel_tower.png
Normal file
BIN
40 Simple GUI Quiz/eiffel_tower.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 MiB |
BIN
40 Simple GUI Quiz/landmark_icon.png
Normal file
BIN
40 Simple GUI Quiz/landmark_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 415 B |
69
40 Simple GUI Quiz/landmark_quiz.py
Normal file
69
40 Simple GUI Quiz/landmark_quiz.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import messagebox
|
||||||
|
from pathlib import Path
|
||||||
|
from PIL import Image, ImageTk
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
root = tk.Tk()
|
||||||
|
root.title("Landmark Quiz")
|
||||||
|
root.geometry("600x560")
|
||||||
|
root.resizable(False, False)
|
||||||
|
|
||||||
|
# Load and resize landmark image
|
||||||
|
image = Image.open(ROOT / "eiffel_tower.png")
|
||||||
|
image = image.resize((300, 300))
|
||||||
|
|
||||||
|
landmark = ImageTk.PhotoImage(image)
|
||||||
|
|
||||||
|
# Window icon
|
||||||
|
icon = tk.PhotoImage(file=ROOT / "landmark_icon.png")
|
||||||
|
root.iconphoto(False, icon)
|
||||||
|
|
||||||
|
title = tk.Label(root, text="Famous Landmark Quiz", font=("Arial", 20, "bold"))
|
||||||
|
title.grid(row=0, column=0, columnspan=2, pady=(15, 10))
|
||||||
|
|
||||||
|
picture = tk.Label(root, image=landmark)
|
||||||
|
picture.grid(row=1, column=0, columnspan=2, padx=20, pady=10)
|
||||||
|
|
||||||
|
question = tk.Label(
|
||||||
|
root,
|
||||||
|
text="Which city is this landmark situated in?",
|
||||||
|
font=("Arial", 13)
|
||||||
|
)
|
||||||
|
question.grid(row=2, column=0, columnspan=2, pady=8)
|
||||||
|
|
||||||
|
entry = tk.Entry(root, width=30, font=("Arial", 12))
|
||||||
|
entry.grid(row=3, column=0, columnspan=2, pady=8)
|
||||||
|
entry.focus()
|
||||||
|
|
||||||
|
result = tk.Label(root, text="", font=("Arial", 12))
|
||||||
|
result.grid(row=5, column=0, columnspan=2, pady=10)
|
||||||
|
|
||||||
|
def check_answer():
|
||||||
|
answer = entry.get().strip().lower()
|
||||||
|
|
||||||
|
if answer == "paris":
|
||||||
|
result.config(text="Correct! The Eiffel Tower is in Paris.")
|
||||||
|
messagebox.showinfo("Correct", "Well done! Paris is the correct answer.")
|
||||||
|
entry.delete(0, tk.END)
|
||||||
|
else:
|
||||||
|
result.config(text="That answer is incorrect. Try again.")
|
||||||
|
messagebox.showerror("Try again", "Incorrect. Please try again.")
|
||||||
|
entry.select_range(0, tk.END)
|
||||||
|
entry.focus()
|
||||||
|
|
||||||
|
def clear_answer():
|
||||||
|
entry.delete(0, tk.END)
|
||||||
|
result.config(text="")
|
||||||
|
entry.focus()
|
||||||
|
|
||||||
|
check_button = tk.Button(root, text="Check answer", command=check_answer, width=16)
|
||||||
|
check_button.grid(row=4, column=0, padx=10, pady=5)
|
||||||
|
|
||||||
|
clear_button = tk.Button(root, text="Clear", command=clear_answer, width=16)
|
||||||
|
clear_button.grid(row=4, column=1, padx=10, pady=5)
|
||||||
|
|
||||||
|
root.bind("<Return>", lambda event: check_answer())
|
||||||
|
|
||||||
|
root.mainloop()
|
||||||
BIN
41 Complete the update feature/address_book.db
Normal file
BIN
41 Complete the update feature/address_book.db
Normal file
Binary file not shown.
215
41 Complete the update feature/address_book.py
Normal file
215
41 Complete the update feature/address_book.py
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import ttk, messagebox
|
||||||
|
import sqlite3
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent
|
||||||
|
DB = ROOT / "address_book.db"
|
||||||
|
|
||||||
|
root = tk.Tk()
|
||||||
|
root.title("Address Book")
|
||||||
|
root.geometry("620x620")
|
||||||
|
root.resizable(False, False)
|
||||||
|
|
||||||
|
def connect():
|
||||||
|
return sqlite3.connect(DB)
|
||||||
|
|
||||||
|
def clear_entries():
|
||||||
|
f_name.delete(0, tk.END)
|
||||||
|
s_name.delete(0, tk.END)
|
||||||
|
mob.delete(0, tk.END)
|
||||||
|
email.delete(0, tk.END)
|
||||||
|
|
||||||
|
def submit():
|
||||||
|
values = (
|
||||||
|
f_name.get().strip(),
|
||||||
|
s_name.get().strip(),
|
||||||
|
mob.get().strip(),
|
||||||
|
email.get().strip(),
|
||||||
|
)
|
||||||
|
|
||||||
|
if not all(values):
|
||||||
|
messagebox.showwarning("Missing data", "Please fill in all four fields.")
|
||||||
|
return
|
||||||
|
|
||||||
|
conn = connect()
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO address_book (f_name, s_name, mob, email)
|
||||||
|
VALUES (?, ?, ?, ?)
|
||||||
|
""",
|
||||||
|
values,
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
clear_entries()
|
||||||
|
search()
|
||||||
|
|
||||||
|
def search():
|
||||||
|
conn = connect()
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("""
|
||||||
|
SELECT f_name, s_name, mob, email, oid
|
||||||
|
FROM address_book
|
||||||
|
ORDER BY oid
|
||||||
|
""")
|
||||||
|
records = c.fetchall()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
output.delete("1.0", tk.END)
|
||||||
|
|
||||||
|
if not records:
|
||||||
|
output.insert(tk.END, "No records found.")
|
||||||
|
return
|
||||||
|
|
||||||
|
for record in records:
|
||||||
|
output.insert(
|
||||||
|
tk.END,
|
||||||
|
f"OID: {record[4]} | "
|
||||||
|
f"{record[0]} {record[1]} | "
|
||||||
|
f"Mobile: {record[2]} | "
|
||||||
|
f"Email: {record[3]}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete_rec():
|
||||||
|
oid = id_no.get().strip()
|
||||||
|
|
||||||
|
if not oid.isdigit():
|
||||||
|
messagebox.showwarning("Invalid OID", "Enter a valid numeric OID.")
|
||||||
|
return
|
||||||
|
|
||||||
|
conn = connect()
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("DELETE FROM address_book WHERE oid = ?", (int(oid),))
|
||||||
|
deleted = c.rowcount
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
id_no.delete(0, tk.END)
|
||||||
|
|
||||||
|
if deleted:
|
||||||
|
messagebox.showinfo("Deleted", f"Record {oid} was deleted.")
|
||||||
|
else:
|
||||||
|
messagebox.showwarning("Not found", f"No record with OID {oid} exists.")
|
||||||
|
|
||||||
|
search()
|
||||||
|
|
||||||
|
def update_rec():
|
||||||
|
oid = id_no.get().strip()
|
||||||
|
column = update_column.get()
|
||||||
|
value = update_value.get().strip()
|
||||||
|
|
||||||
|
allowed_columns = {
|
||||||
|
"First Name": "f_name",
|
||||||
|
"Surname": "s_name",
|
||||||
|
"Mobile": "mob",
|
||||||
|
"Email": "email",
|
||||||
|
}
|
||||||
|
|
||||||
|
if not oid.isdigit():
|
||||||
|
messagebox.showwarning("Invalid OID", "Enter a valid numeric OID.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not value:
|
||||||
|
messagebox.showwarning("Missing value", "Enter the new value.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# The column name cannot be passed as a normal SQL parameter,
|
||||||
|
# so only a value from this fixed whitelist is allowed.
|
||||||
|
db_column = allowed_columns[column]
|
||||||
|
|
||||||
|
conn = connect()
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
sql = "UPDATE address_book SET {} = ? WHERE oid = ?".format(db_column)
|
||||||
|
c.execute(sql, (value, int(oid)))
|
||||||
|
updated = c.rowcount
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if updated:
|
||||||
|
messagebox.showinfo(
|
||||||
|
"Updated",
|
||||||
|
f"Record {oid} was updated successfully."
|
||||||
|
)
|
||||||
|
id_no.delete(0, tk.END)
|
||||||
|
update_value.delete(0, tk.END)
|
||||||
|
search()
|
||||||
|
else:
|
||||||
|
messagebox.showwarning(
|
||||||
|
"Not found",
|
||||||
|
f"No record with OID {oid} exists."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create database/table if it does not already exist.
|
||||||
|
conn = connect()
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("""
|
||||||
|
CREATE TABLE IF NOT EXISTS address_book (
|
||||||
|
f_name TEXT,
|
||||||
|
s_name TEXT,
|
||||||
|
mob TEXT,
|
||||||
|
email TEXT
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
# ---------- GUI ----------
|
||||||
|
tk.Label(root, text="First Name").grid(row=0, column=0, sticky="e", padx=8, pady=6)
|
||||||
|
f_name = tk.Entry(root, width=35)
|
||||||
|
f_name.grid(row=0, column=1, padx=8, pady=6)
|
||||||
|
|
||||||
|
tk.Label(root, text="Surname").grid(row=1, column=0, sticky="e", padx=8, pady=6)
|
||||||
|
s_name = tk.Entry(root, width=35)
|
||||||
|
s_name.grid(row=1, column=1, padx=8, pady=6)
|
||||||
|
|
||||||
|
tk.Label(root, text="Mobile").grid(row=2, column=0, sticky="e", padx=8, pady=6)
|
||||||
|
mob = tk.Entry(root, width=35)
|
||||||
|
mob.grid(row=2, column=1, padx=8, pady=6)
|
||||||
|
|
||||||
|
tk.Label(root, text="Email").grid(row=3, column=0, sticky="e", padx=8, pady=6)
|
||||||
|
email = tk.Entry(root, width=35)
|
||||||
|
email.grid(row=3, column=1, padx=8, pady=6)
|
||||||
|
|
||||||
|
tk.Button(root, text="Save", command=submit, width=14).grid(
|
||||||
|
row=4, column=0, padx=8, pady=10
|
||||||
|
)
|
||||||
|
tk.Button(root, text="Display all", command=search, width=14).grid(
|
||||||
|
row=4, column=1, sticky="w", padx=8, pady=10
|
||||||
|
)
|
||||||
|
|
||||||
|
tk.Label(root, text="Enter OID").grid(row=5, column=0, sticky="e", padx=8, pady=6)
|
||||||
|
id_no = tk.Entry(root, width=35)
|
||||||
|
id_no.grid(row=5, column=1, padx=8, pady=6)
|
||||||
|
|
||||||
|
tk.Button(root, text="Delete", command=delete_rec, width=14).grid(
|
||||||
|
row=6, column=0, padx=8, pady=8
|
||||||
|
)
|
||||||
|
|
||||||
|
tk.Label(root, text="Update field").grid(row=7, column=0, sticky="e", padx=8, pady=6)
|
||||||
|
update_column = ttk.Combobox(
|
||||||
|
root,
|
||||||
|
values=("First Name", "Surname", "Mobile", "Email"),
|
||||||
|
state="readonly",
|
||||||
|
width=32,
|
||||||
|
)
|
||||||
|
update_column.current(0)
|
||||||
|
update_column.grid(row=7, column=1, padx=8, pady=6)
|
||||||
|
|
||||||
|
tk.Label(root, text="New value").grid(row=8, column=0, sticky="e", padx=8, pady=6)
|
||||||
|
update_value = tk.Entry(root, width=35)
|
||||||
|
update_value.grid(row=8, column=1, padx=8, pady=6)
|
||||||
|
|
||||||
|
tk.Button(root, text="Update", command=update_rec, width=14).grid(
|
||||||
|
row=9, column=0, columnspan=2, pady=8
|
||||||
|
)
|
||||||
|
|
||||||
|
output = tk.Text(root, width=72, height=13, wrap="word")
|
||||||
|
output.grid(row=10, column=0, columnspan=2, padx=10, pady=12)
|
||||||
|
|
||||||
|
search()
|
||||||
|
root.mainloop()
|
||||||
Loading…
Reference in New Issue
Block a user