Create a Quiz App with Tkinter & Pandas Subtitle: Step-by-step tutorial — Python GUI reading questions from Excel Small note: Requires Python 3.8+ and pandas installed.
What you will learn
-
How to prepare an Excel file with questions.
-
How to load questions using
pandas. -
How to build the Tkinter UI (buttons, labels, images).
-
How to implement quiz logic: scoring, navigation and restart.
-
How to customize the look and pack your app.
Prerequisites
-
Python 3.8+ installed.
-
Basic Python knowledge (functions, lists, variables).
-
Install
pandaswith:
pip install pandas openpyxl
(openpyxl is used by pandas to read .xlsx files.)
Project files
Create a project folder with these files:
-
quiz_app.py— the Python script (code below) -
questions.xlsx— Excel file with questions and options -
logo.png— small logo image for the app (optional)
Prepare questions.xlsx
Create an Excel file with these columns in the first row (header):
question | option1 | option2 | option3 | option4 | answer
-
question— the question text. -
option1..option4— the four choices. -
answer— integer 1..4 pointing to the correct option.
Add at least 10 rows (each row is a question). Save as questions.xlsx in the same folder as the script.
Full code (copy into quiz_app.py)
import tkinter as tk
from tkinter import messagebox
from tkinter import PhotoImage
import pandas as pd
import random
# Load the excel file
df = pd.read_excel('questions.xlsx')
# Randomly select questions
questions = df.sample(n=10).values.tolist()
# Global variables
score = 0
current_question = 0
# Function to display the next Question
def display_question():
question, option1, option2, option3, option4, answer = questions[current_question]
question_label.config(text=question)
option1_btn.config(text=option1, state=tk.NORMAL, command=lambda: check_answer(1))
option2_btn.config(text=option2, state=tk.NORMAL, command=lambda: check_answer(2))
option3_btn.config(text=option3, state=tk.NORMAL, command=lambda: check_answer(3))
option4_btn.config(text=option4, state=tk.NORMAL, command=lambda: check_answer(4))
correct_answer.set(answer)
# Funcytion to check the answer
def check_answer(answer):
global score, current_question
if answer == correct_answer.get():
score +=1
current_question +=1
if current_question < len(questions):
display_question()
else:
show_result()
# function to show the results
def show_result():
messagebox.showinfo("Quiz Completed", f"Congratulations you finished the quiz. \n\nFinal Score: {score}/{len(questions)}")
option1_btn.config(state=tk.DISABLED)
option2_btn.config(state=tk.DISABLED)
option3_btn.config(state=tk.DISABLED)
option4_btn.config(state=tk.DISABLED)
play_again_btn.pack()
# function to play agin
def play_again():
global score, current_question
score = 0
current_question = 0
random.shuffle(questions)
display_question()
option1_btn.config(state=tk.NORMAL)
option2_btn.config(state=tk.NORMAL)
option3_btn.config(state=tk.NORMAL)
option4_btn.config(state=tk.NORMAL)
play_again_btn.pack_forget()
# Define
background_color = "#ECECEC"
text_color = "#333333"
button_color = "#4CAF50"
button_text_color = "#FFFFFF"
#window
window = tk.Tk()
window.title("Quiz App")
window.geometry("400x450")
window.config(bg=background_color)
window.option_add('*Font', "Arial")
# App logo
app_icon = PhotoImage(file='logo.png')
app_label = tk.Label(window, image=app_icon, bg=background_color)
app_label.pack(pady=10)
# interface components
question_label = tk.Label(window, text="Hello Joao",wraplength=380, bg=background_color,fg=text_color, font=("Arial", 12, "bold") )
question_label.pack(pady=20)
correct_answer = tk.IntVar()
option1_btn = tk.Button(window, text="", width=30, bg=button_color,fg=button_text_color, state=tk.DISABLED, font=("Arial", 10, "bold") )
option1_btn.pack(pady=10)
option2_btn = tk.Button(window, text="", width=30, bg=button_color,fg=button_text_color, state=tk.DISABLED, font=("Arial", 10, "bold") )
option2_btn.pack(pady=10)
option3_btn = tk.Button(window, text="", width=30, bg=button_color,fg=button_text_color, state=tk.DISABLED, font=("Arial", 10, "bold") )
option3_btn.pack(pady=10)
option4_btn = tk.Button(window, text="", width=30, bg=button_color,fg=button_text_color, state=tk.DISABLED, font=("Arial", 10, "bold") )
option4_btn.pack(pady=10)
play_again_btn = tk.Button(window, text="Play Again", width=30, bg=button_color,fg=button_text_color, font=("Arial", 10, "bold"), command=play_again )
display_question()
window.mainloop()
Explain the main parts
-
Load questions:
df = pd.read_excel('questions.xlsx')reads your Excel into a DataFrame. -
Random sample:
df.sample(n=10)picks 10 questions at random. -
State variables:
scoreandcurrent_questiontrack progress. -
display_question(): writes the current question and attaches button callbacks.
-
check_answer(): compares the chosen answer with the correct one and updates the score.
-
show_result(): displays the final score with a popup and disables buttons.
Tips & improvements
-
Validate the Excel file (empty rows, missing columns) before using.
-
Use
try/exceptaroundpd.read_excelto show a friendly error if file missing. -
Add a progress bar or question counter: "Question 3 / 10".
-
Add categories: include a
categorycolumn and filter by it before sampling. -
Save high scores to a local file (CSV) to show the best scores.
Styling suggestions for Canva
-
Use a clean header font (e.g., Montserrat) for titles.
-
Use code blocks with a monospaced font (Courier New) and a subtle gray background.
-
Add screenshots of the running app: take a screenshot on your OS and paste into Canva.
-
Use icons for each step (install, file, code, run) to make slides visual.
Final notes & sharing
-
To run: open a terminal in the project folder and run
python quiz_app.py. -
If you plan to share on GitHub, include
requirements.txtwithpandasandopenpyxl.
Copyright statement: Unless otherwise indicated, all articles are original to this site, please cite the source when sharing.
Article link:http://pybeginners.com/python-projects/how-to-build-a-quiz-app-in-python-using-tkinter-and-pandas/
License agreement:Creative Commons Attribution-NonCommercial 4.0 International License