In this tutorial, weβll build a desktop chatbot that helps users get information about condos. The app allows users to select a condo, category, and question, then receive a response. Youβll also be able to manage Q&A data via an admin interface.
Weβll use:
Python 3
Tkinter for GUI
JSON for storing Q&A data
sv_ttk for modern themes
Step 1: Project Setup
First, make sure you have Python installed (3.7+ recommended). Then install the sv_ttk theme library:
pip install sv-tk
Next, create a new Python file, e.g., condo_bot.py, and start by importing required modules:
import sys
import os
import json
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import sv_ttk
Explanation:
tkinter β GUI toolkit
ttk β themed widgets
messagebox & simpledialog β for alerts and prompts
json β storing Q&A data
sv_ttk β modern light/dark theme for Tkinter
Step 2: Handling Resource Paths and Q&A Data
We need a JSON file to store our condo Q&A data. Letβs create helper functions to load and save this data.
QA_FILE = "qa_data.json"
def load_qa():
if os.path.exists(QA_FILE):
with open(QA_FILE, "r", encoding="utf-8") as f:
return json.load(f)
else:
# Default Q&A
return [
{"condo": "Condo A", "category": "Sell", "question": "Sell Condo", "response": "We can assist with selling Condo A."},
{"condo": "Condo A", "category": "Rent", "question": "Rent Condo", "response": "We can list Condo A for rent."},
{"condo": "Condo B", "category": "Price", "question": "Price", "response": "Condo B prices vary by floor and size."},
{"condo": "Condo B", "category": "Service Fee", "question": "Service Fee", "response": "Service fee depends on condo type."},
{"condo": "Condo C", "category": "Facilities", "question": "Facilities", "response": "Condo C has gym, pool, and security."},
]
def save_qa():
with open(QA_FILE, "w", encoding="utf-8") as f:
json.dump(qa_data, f, ensure_ascii=False, indent=4)
Explanation:
If the JSON file exists, we load it.
Otherwise, we use default sample Q&A.
save_qa() writes any changes back to the JSON file.
Step 3: Initialize the Tkinter App
Letβs set up the main window and apply a modern theme:
root = tk.Tk()
root.title("π¬ Condo Assistant Bot")
root.geometry("1180x650")
sv_ttk.set_theme("light")
title() β Window title
geometry() β Window size
sv_ttk.set_theme("light") β Applies a clean light theme
Step 4: Define Global Variables
We need to store Q&A data and some state variables:
qa_data = load_qa()
dark_mode_var = tk.BooleanVar(value=False)
status_var = tk.StringVar(value="Ready")
qa_data β Stores all condo Q&A
dark_mode_var β Optional toggle for dark mode
status_var β For showing status messages at the bottom
Step 5: Helper Functions for Chat Logic
These functions make it easy to fetch condos, categories, questions, and responses:
def get_condos():
return sorted(list({qa["condo"] for qa in qa_data}))
def get_categories(condo):
return sorted(list({qa["category"] for qa in qa_data if qa["condo"] == condo}))
def get_questions(condo, category):
return [qa["question"] for qa in qa_data if qa["condo"] == condo and qa["category"] == category]
def get_response(condo, category, question):
for qa in qa_data:
if qa["condo"] == condo and qa["category"] == category and qa["question"] == question:
return qa["response"]
return "No response found."
Explanation:
We use list comprehensions and sets to get unique condos and categories.
get_response() returns the answer based on user selection.
Step 6: Create the Chat Bubble Function
To make it look like a real chat, weβll add a bubble-style text insert:
def insert_bubble(message, sender="user"):
chat_text.config(state="normal")
if sender == "user":
chat_text.insert(tk.END, f" {message} \n\n", "user_bubble")
else:
chat_text.insert(tk.END, f" {message} \n\n", "bot_bubble")
chat_text.see(tk.END)
chat_text.config(state="disabled")
chat_text β Text widget for chat
user_bubble and bot_bubble β Different styles for user and bot
Step 7: Build the Main UI Dropdowns
We want users to select Condo β Category β Question:
input_frame = ttk.LabelFrame(root, text="Ask a Question", padding=10)
input_frame.pack(fill="x", pady=8)
condo_combo = ttk.Combobox(input_frame, state="readonly", width=20)
condo_combo.grid(row=0, column=1, padx=5)
condo_combo['values'] = get_condos()
condo_combo.current(0)
category_combo = ttk.Combobox(input_frame, state="readonly", width=20)
category_combo.grid(row=0, column=3, padx=5)
question_combo = ttk.Combobox(input_frame, state="readonly", width=30)
question_combo.grid(row=0, column=5, padx=5)
Combobox β Dropdown selection
Users select in hierarchical order: Condo β Category β Question
Update dropdowns dynamically:
def update_category_dropdown(event=None):
selected_condo = condo_combo.get()
categories = get_categories(selected_condo)
category_combo['values'] = categories
if categories: category_combo.current(0)
update_question_dropdown()
def update_question_dropdown(event=None):
selected_condo = condo_combo.get()
selected_category = category_combo.get()
questions = get_questions(selected_condo, selected_category)
question_combo['values'] = questions
if questions: question_combo.current(0)
condo_combo.bind("<<ComboboxSelected>>", update_category_dropdown)
category_combo.bind("<<ComboboxSelected>>", update_question_dropdown)
update_category_dropdown()
update_question_dropdown()
Step 8: Send Message Function
When users ask a question:
def send_message():
condo = condo_combo.get()
category = category_combo.get()
question = question_combo.get()
if not (condo and category and question):
messagebox.showwarning("Incomplete Selection", "Please select condo, category, and question.")
return
response = get_response(condo, category, question)
insert_bubble(f"You: {condo} | {category} | {question}", "user")
insert_bubble(f"Bot: {response}", "bot")
status_var.set(f"Responded to: {question}")
Shows user message and bot response
Updates status bar
Step 9: Build Admin Q&A Manager
Users can add/update Q&A dynamically:
def manage_qa_ui():
admin_win = tk.Toplevel(root)
admin_win.title("Manage Q&A")
admin_win.geometry("1050x550")
admin_win.transient(root)
admin_win.grab_set()
# Add new Q&A frame
add_frame = ttk.LabelFrame(admin_win, text="β Add New Q&A", padding=10)
add_frame.pack(fill="x", padx=10, pady=5)
# Input fields for condo, category, question, response
# ... (similar to Step 7)
Toplevel β Opens a new window
grab_set() β Makes it modal
Users can add or edit Q&A
Step 10: Create Chat Frame with Scrollbar
chat_text = tk.Text(root, wrap="word", state="disabled", font=("Segoe UI", 12), bg="#f5f5f5")
chat_text.pack(expand=True, fill="both", padx=10, pady=10)
scrollbar = ttk.Scrollbar(root, orient="vertical", command=chat_text.yview)
scrollbar.pack(side="right", fill="y")
chat_text.configure(yscrollcommand=scrollbar.set)
Scrollable text widget for chat
Bubble styling applied using tag_configure
Step 11: Run the App
Finally, run the app:
root.mainloop()
π Thatβs it! You now have a fully functional Condo Assistant Bot with Tkinter.
β What You Can Do Next
Add dark mode toggle
Integrate with real API data for condos
Add search/filter functionality in admin panel
Customize bubble colors and fonts

Top comments (0)