In this tutorial, we’ll build a colorful, animated quiz game using Python and Tkinter—complete with:
Category selection
Countdown timer
Sound effects
Score tracking
Animated confetti 🎊
No advanced Python required—just basic functions, classes, and lists.
🧰 Step 1: Import Required Libraries
Let’s start by importing everything we’ll need.
import tkinter as tk
from tkinter import ttk
import threading
import random
import winsound # Windows only (use playsound for Mac/Linux)
What these do:
tkinter → GUI framework
ttk → modern widgets (progress bar)
threading → play sounds without freezing the UI
random → confetti randomness
winsound → play sound effects on Windows
🧠 Step 2: Create the Quiz Data
We’ll store questions using a dictionary of lists—one list per category.
quiz_categories = {
"General Knowledge": [
{
"question": "What is the capital of France?",
"options": ["Paris", "London", "Berlin", "Madrid"],
"answer": "Paris"
},
{
"question": "Which planet is known as the Red Planet?",
"options": ["Earth", "Mars", "Jupiter", "Venus"],
"answer": "Mars"
}
],
"Literature": [
{
"question": "Who wrote 'Romeo and Juliet'?",
"options": ["Charles Dickens", "William Shakespeare", "Mark Twain", "Jane Austen"],
"answer": "William Shakespeare"
},
{
"question": "Which novel begins with 'Call me Ishmael'?",
"options": ["Moby Dick", "1984", "Great Expectations", "The Odyssey"],
"answer": "Moby Dick"
}
]
}
Why this structure?
Easy to add new categories
Each question contains text, choices, and the correct answer
🏗 Step 3: Create the Main Game Class
Everything lives inside a class to keep things organized.
class MiniGameShow:
def __init__(self, root):
self.root = root
self.root.title("🎉 Mini Game Show 🎉")
self.root.geometry("800x700")
self.root.resizable(False, False)
self.root.configure(bg="#1E1E2F")
Initialize game state variables:
self.score = 0
self.current_question = 0
self.selected_category = None
self.questions = []
self.time_left = 15
self.timer_running = False
self.animating = False
Finally, load the first screen:
self.create_category_screen()
📂 Step 4: Category Selection Screen
This screen lets the player choose a quiz category.
def create_category_screen(self):
self.stop_animations()
self.clear_screen()
Title label:
title = tk.Label(
self.root,
text="Choose Your Category",
font=("Helvetica", 28, "bold"),
fg="#FFD700",
bg="#1E1E2F"
)
title.pack(pady=50)
Generate buttons dynamically:
for category in quiz_categories:
btn = tk.Button(
self.root,
text=category,
font=("Helvetica", 20),
width=25,
bg="#4B0082",
fg="white",
command=lambda c=category: self.start_quiz(c)
)
btn.pack(pady=15)
💡 Why lambda c=category?
It locks in the correct category value for each button.
▶️ Step 5: Start the Quiz
When a category is selected, we reset the game state.
def start_quiz(self, category):
self.selected_category = category
self.questions = quiz_categories[category]
self.current_question = 0
self.score = 0
self.show_question()
❓ Step 6: Display Questions & Options
def show_question(self):
if self.current_question >= len(self.questions):
self.show_result()
return
Reset the screen and timer:
self.clear_screen()
self.time_left = 15
self.timer_running = True
Question label:
question_data = self.questions[self.current_question]
self.question_label = tk.Label(
self.root,
text=question_data["question"],
font=("Helvetica", 22, "bold"),
fg="#00FFFF",
bg="#1E1E2F",
wraplength=750
)
self.question_label.pack(pady=50)
⏱ Step 7: Add a Countdown Timer
self.progress = ttk.Progressbar(
self.root,
orient="horizontal",
length=500,
mode="determinate",
maximum=15
)
self.progress.pack(pady=10)
Timer logic:
def update_timer(self):
if self.time_left >= 0 and self.timer_running:
self.progress["value"] = 15 - self.time_left
self.time_left -= 1
self.root.after(1000, self.update_timer)
else:
self.timer_running = False
self.flash_color("#FF4500")
self.root.after(800, self.next_question)
✅ Step 8: Answer Buttons & Validation
for option in question_data["options"]:
btn = tk.Button(
self.root,
text=option,
font=("Helvetica", 18),
width=30,
bg="#6A5ACD",
fg="white",
command=lambda o=option: self.check_answer(o)
)
btn.pack(pady=10)
Check the answer:
def check_answer(self, selected_option):
if not self.timer_running:
return
self.timer_running = False
correct_answer = self.questions[self.current_question]["answer"]
Correct vs wrong feedback:
if selected_option == correct_answer:
self.score += 1
self.flash_color("#00FF00")
threading.Thread(target=self.play_sound, args=("correct.wav",)).start()
else:
self.flash_color("#FF4500")
threading.Thread(target=self.play_sound, args=("wrong.wav",)).start()
self.root.after(800, self.next_question)
🎊 Step 9: Results Screen with Confetti
def show_result(self):
self.clear_screen()
self.animating = True
Canvas setup:
self.canvas = tk.Canvas(
self.root,
width=800,
height=600,
bg="#1E1E2F",
highlightthickness=0
)
self.canvas.pack()
Score text:
self.result_text_id = self.canvas.create_text(
400, 100,
text=f"🏆 Game Over! Your Score: {self.score}/{len(self.questions)} 🏆",
font=("Helvetica", 24, "bold"),
fill="#FFD700"
)
Confetti count scales with score 🎉:
particles_count = 50 + self.score * 50
self.confetti_particles = []
self.create_confetti(particles_count)
🎈 Step 10: Confetti Animation Logic
Create particles:
def create_confetti(self, count):
for _ in range(count):
self.confetti_particles.append({
"x": random.randint(0, 800),
"y": random.randint(-600, 0),
"size": random.randint(5, 12),
"color": random.choice(["#FF0000", "#00FF00", "#0000FF"]),
"speed": random.randint(3, 8)
})
Animate them:
def animate_confetti(self):
if not self.animating:
return
self.canvas.delete("confetti")
for p in self.confetti_particles:
p["y"] += p["speed"]
if p["y"] > 600:
p["y"] = random.randint(-100, 0)
self.canvas.create_oval(
p["x"], p["y"],
p["x"] + p["size"], p["y"] + p["size"],
fill=p["color"],
outline="",
tags="confetti"
)
self.root.after(50, self.animate_confetti)
🚀 Step 11: Run the App
if __name__ == "__main__":
root = tk.Tk()
game = MiniGameShow(root)
root.mainloop()
🧠 Final Thoughts
You’ve just built a fully interactive quiz game with:
UI state management
Timers
Threads
Animation
Sound effects
Want to extend it?
Add more categories
Load questions from a JSON file
Add difficulty levels
Add keyboard shortcuts
Top comments (0)