DEV Community

Mate Technologies
Mate Technologies

Posted on

Build a Condo Assistant Chatbot with Python and Tkinter πŸ’¬

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

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."
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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}")
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode
# Input fields for condo, category, question, response
# ... (similar to Step 7)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Scrollable text widget for chat

Bubble styling applied using tag_configure

Step 11: Run the App

Finally, run the app:

root.mainloop()
Enter fullscreen mode Exit fullscreen mode

πŸŽ‰ 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

Condo Assistant Bot

Top comments (0)