LEARN PYTHON | Project: A Desktop Study Planner

Lesson objective

Build a Tkinter study planner with persistent tasks, filters, stable selection IDs, input rejection and a non-blocking focus timer.

Learn

08.5 | PROJECT: A DESKTOP STUDY PLANNER

01 | THE BRIEF: TURN INTENTIONS INTO TASKS

A learner needs to record a subject, a specific study task, a due date and planned minutes. They want to mark tasks complete, find open work and reopen a task if necessary. Those records must survive closing the window.

A separate focus timer helps with a short work session. Its countdown should not prevent editing the task list or moving the window. Planned minutes describe intention, not proof that the work actually happened.

Download the complete project below. It uses Tkinter, SQLite and other standard modules. No third-party package is required, but your Python installation must include Tk support and have a desktop display. Use Python 3.10 or later.

Download the desktop study planner

02 | DEFINE THE ACCEPTANCE RULES

Subjects and task titles must be trimmed, non-blank text. The subject limit is forty characters and the task limit is eighty. Due dates must be real YYYY-MM-DD dates. Planned minutes must be a whole number from one to 240.

The task list shows all, open or completed records in due-date then ID order. Completion and reopening update the selected record. Deletion asks for confirmation because it permanently removes that record.

The focus timer accepts one to 120 whole minutes. Starting again replaces its deadline, cancelling stops it, and closing the application cancels scheduled refresh work. Saved tasks persist; the timer and current selection do not.

03 | SPLIT MODEL FROM INTERFACE

model.py defines StudyStore for validation and database operations, plus FocusTimer for elapsed-time rules. app.py creates the widgets and connects their callbacks to those services. test_model.py checks the core using temporary databases and a supplied clock.

A model owns meaningful data and rules. A view shows it, and callbacks coordinate user requests. This small separation is not a promise of one universal architecture; it makes this project understandable and testable.

Do not put input() inside a GUI callback to request missing data. Read the existing form controls and display feedback instead. The user should remain within the interface they opened.

FileResponsibility
model.pyStudyStore, validation and FocusTimer
app.pyTkinter widgets, selection, callbacks and rendering
test_model.py13 automated tests without opening a GUI
study.sqlite3Created beside app.py to retain tasks
README.txtSetup, workflow, limitations and manual checks

04 | RUN A SMALL END-TO-END TRIAL

Extract the download, select the intended interpreter and run the commands below in its folder. The model tests do not need a display, but app.py does.

Add “Computer Science”, “Trace a nested loop”, 2026-10-15 and 25 minutes. Select its row and click Complete selected. Change the filter to completed, then reopen it.

Close the application and run it again. The accepted task should still be present because a committed SQLite file stores it. This restart test is different from refreshing the browser illustration.

TERMINAL | PROJECT FOLDER

python -m tkinter
python app.py
python -m unittest discover -s . -v

05 | GIVE A ROW ITS REAL RECORD ID

A displayed row is not the database record’s identity. Sorting or filtering can change its position. The project inserts each Treeview item with iid=str(row["id"]), keeping a stable connection to the database key.

selected_id obtains the selected item identifier and converts it to an integer. With no selection it shows a helpful message and returns None. Completion callbacks stop there instead of accidentally changing some default record.

After a refresh, the code restores the previous selection only if that ID remains in the filtered list. Completing a task in the open filter makes it disappear from that view, which is expected rather than data loss.

PYTHON | EXCERPT FROM THE UI, NOT A STANDALONE FILE

selection = self.tree.selection()
if selection:
    task_id = int(selection[0])
    self.store.set_done(task_id, True)
    self.refresh()

06 | SAVE BEFORE CLEARING THE FORM

The add callback reads StringVar values, converts minutes to int and calls store.add. The store checks text, date and allowed minutes before inserting with bound parameters.

If validation or a SQLite operation fails, the callback reports “Not saved” and leaves the task field available for correction. Only after successful storage does it clear the task text and refresh the report.

refresh reads rows first, then replaces displayed items. A read error should not erase the last successful display and pretend the database is empty. The callback reports the failure instead.

07 | MAKE THE TIMER A SMALL INDEPENDENT MODEL

FocusTimer stores a deadline measured on its supplied clock. remaining calculates the duration still available and rounds upward to show a positive second until expiry. At the deadline it clears the timer.

The default clock is time.monotonic. In a test, a simple callable supplies a controlled number so sixty seconds can pass instantly without sleeping. The sample below belongs beside the downloaded model.py.

The GUI uses one recurring after callback to refresh the display about every 250 milliseconds. It does not start an additional callback chain each time Start is pressed.

from model import FocusTimer

now = [100.0]
timer = FocusTimer(clock=lambda: now[0])
timer.start(1)
print("Start:", timer.remaining())
now[0] = 130.5
print("Later:", timer.remaining())
now[0] = 160.0
print("Deadline:", timer.remaining())

EXPECTED OUTPUT

Start: 60
Later: 30
Deadline: 0

08 | EXPLORE TASK STATE

This page-session model illustrates add, complete and reopen. It does not open SQLite and its records disappear on page reload. Use the downloaded desktop app for persistent records and the actual timer.

09 | TEST THE MODEL AND THE HUMAN WORKFLOW

The thirteen automated tests check persistence, SQL-looking input as data, invalid text and dates, minute limits, completion/reopening, deletion, missing IDs, fixed filters, ordering and clock-based countdown behaviour. Temporary databases protect real saved records.

Manual interface tests cover things the model alone cannot: Tab navigation, Enter submission, selecting the intended row, resizing, scrollbar operation and confirmation dialogs. Cancel deletion and check the row remains.

Start a one-minute timer, keep using the form and close while it is running. Reopen: task records remain, but the focus session starts fresh. The project makes that data-lifetime distinction visible.

10 | HAND OVER AND EXTEND DELIBERATELY

The database is study.sqlite3 beside app.py. Back it up with the application closed in this teaching setup. Keep it out of public Git history, together with environments and real private data.

This is a local single-user learning tool without accounts, encrypted storage or automatic schema migrations. If you add categories or priorities, plan how existing rows will move to the changed schema. CREATE TABLE IF NOT EXISTS will not update old columns.

Useful extensions include editing a selected task, subject filters, CSV export and keyboard shortcuts. Write the expected behaviour and rejection cases first, then implement one feature and rerun existing tests.

OFFICIAL REFERENCE

Use the worked examples first, then consult the official documentation to check widget, input or drawing options. Match it to the version selected in your project environment.

PUT YOUR SKILLS TO WORK

Use the Section 8 challenges to practise these ideas independently. Work in your Python editor, predict results and keep a short test record.

Section 8 challenges Python course navigation

MATCH THE PYTHON TERM TO ITS MEANING

Terminology

Terminology

Model

Data and rules independent of a particular visual representation.

View

The interface representation of model state.

StudyStore

The project service validating and persisting study tasks.

Treeview

A Tkinter widget displaying structured rows.

Item identifier

A stable identifier assigned to a Treeview item.

Selection

The interface item currently chosen for an action.

Persistence

Retaining accepted records after the program closes.

Refresh

Rebuilding displayed information from current model state.

Filter

A rule choosing which records to display.

Completion flag

A value marking whether a task is complete.

FocusTimer

The project’s deadline-based countdown model.

Clock injection

Supplying a time source explicitly to make timing tests repeatable.

Confirmation

An explicit choice before a destructive interface action.

Planned minutes

The intended study duration, not measured completed work.

TemporaryDirectory

A standard-library helper managing a disposable test folder.

Regression test

A check that existing behaviour still works after a change.

Data lifetime

How long a particular kind of state is retained.

Schema migration

A deliberate transition for existing stored structure and records.

Questions

Questions

CHECK YOUR UNDERSTANDING

Select all correct choices. Each exact set earns one point.

1. What does the Treeview item ID represent in the planner?
2. When should the add callback clear the task field?
3. Which values survive restarting this project?
4. What is allowed for planned minutes?
5. Why might a completed task disappear in the open filter?
6. How does the timer avoid waiting in automated tests?
7. What must still be checked manually?
8. What does IF NOT EXISTS not do?

EXPLAIN AND COMPARE

Write your answers before revealing each sample.

1. Explain stable selection identity.

2. Describe an accepted Add action.

3. Explain the two data lifetimes.

4. Explain a task disappearing after completion.

5. Describe the focus timer algorithm.

6. Design a rejection test.

7. Evaluate automated and manual checks.

8. Suggest one responsible extension.

CODE IT | YOUR INDEPENDENT CHALLENGE

Build the planner, test saved records and timer rules, then check native interface usability.

Work in your Python editor. Keep a working version, explain one design choice and record at least two tests. Use the Learn tab for worked examples before comparing your result.

Flashcards

Flashcards

Click to flip. Select the ideas you need to revisit.

0 cards selected for revision.

    Selections are kept while this page is open.

    Workbook

    Workbook

    COMING SOON

    The workbook for Project: A Desktop Study Planner is coming soon. Complete the matching task and written questions in your exercise book.