GUI and Backend Integration
GUI and Backend Integration
Now you will connect your GUI to your backend logic.
This is where your application becomes interactive and functional.
Users will be able to:
- register
- log in
- see their dashboard with real summary data
- log out and return to the login screen
Goal of This Lesson
By the end of this lesson, you will:
- connect the Login button to authentication logic
- connect the Create Account button to registration logic
- switch between login and dashboard screens
- display real summary data in the stat cards
- support logout
Step 1: Import Services in UI
Open:
app/ui/app_ui.py
Add at the top, with the other imports:
from app.services.user_service import login_user, register_user
from app.services.dashboard_service import get_dashboard_data
Step 2: Wire Up the Login Screen
In the previous lesson, your show_login buttons used lambda: None as placeholders.
Replace them with real handlers.
Inside show_login(window), after the password_entry is created, define the handlers:
def handle_login():
username = username_entry.get().strip()
password = password_entry.get().strip()
if not username or not password:
message_label.config(text="Enter username and password",
fg=THEME["danger"])
return
user_id = login_user(username, password)
if user_id:
show_dashboard(window, user_id, username)
else:
message_label.config(text="Invalid login", fg=THEME["danger"])
def handle_register():
username = username_entry.get().strip()
password = password_entry.get().strip()
if not username or not password:
message_label.config(text="Enter username and password",
fg=THEME["danger"])
return
if register_user(username, password):
message_label.config(text="Account created — you can log in now",
fg=THEME["success"])
else:
message_label.config(text="Username already taken",
fg=THEME["danger"])
Now replace the placeholder buttons:
_styled_button(card, "Login", handle_login, "primary").pack(
fill="x", padx=40, pady=(8, 6), ipady=4)
_styled_button(card, "Create account", handle_register, "success").pack(
fill="x", padx=40, pady=(0, 20), ipady=4)
Step 3: Add Keyboard Shortcuts
Real apps let users press Enter to submit a form.
At the bottom of show_login, add:
username_entry.bind("<Return>", lambda _e: handle_login())
password_entry.bind("<Return>", lambda _e: handle_login())
username_entry.focus_set()
focus_set() puts the cursor in the username field automatically.
Step 4: Display Real Data in the Stat Cards
In the previous lesson, the stat cards showed "0", "0", and "$0" as placeholders.
Now you will fill them with real data from dashboard_service.
Inside show_dashboard(window, user_id, username=""), after building the stat cards, add a refresh function and call it:
def refresh_summary():
data = get_dashboard_data(user_id)
stat_total["value"].config(text=str(data["total_tasks"]))
stat_done["value"].config(text=str(data["completed_tasks"]))
total = data["total_expenses"]
if isinstance(total, float) and total.is_integer():
total = int(total)
stat_expense["value"].config(text=f"${total}")
refresh_summary()
Notice how this works:
stat_total["value"]is the big-number label returned by_build_stat_card.config(text=...)updates its text- You call
refresh_summary()once now, but you will call it again later whenever data changes
Step 5: Update main.py
Your main.py should already look like this from Lesson 7:
from app.services.database import create_tables
from app.ui.app_ui import create_app, show_login
def main():
create_tables()
window = create_app()
show_login(window)
window.mainloop()
if __name__ == "__main__":
main()
No changes needed.
What Happens Now
- User opens the app
- Login screen appears (centered card)
- User enters credentials, presses Enter or clicks Login
- App checks the database
- If valid:
- login screen is replaced by the dashboard
- stat cards show real values from the database
- User can click Logout to return to the login screen
Important Flow
GUI → user input → service → database → result → GUI update
Important Notes
- Do not put database logic inside UI
- UI should call service functions only
- Always validate user input
- Use
_clear(window)before showing a new screen (handled insideshow_loginandshow_dashboard) - The
usernameparameter inshow_dashboardis optional but lets you show “Welcome, demo” in the header
Current Project Structure
app/
services/
database.py
user_service.py
task_service.py
expense_service.py
dashboard_service.py
ui/
app_ui.py
What Is Still Missing
Your app now supports:
- registration
- login
- dashboard with real summary data
- logout
The two panels (Tasks and Expenses) are still empty.
Next, you will fill them with full task and expense management.
Summary
You connected your GUI with backend logic, enabling real user interaction and dynamic data display in the stat cards.
Next Step
lesson-10-feature-integration.md
This is where your app becomes fully interactive (tasks + expenses in GUI).