PROTOCOL 02 / PRESENTATION

Tkinter and Turtle: The Garden Interface

1–2 sessions Foundation Eden research series

Learning outcomes

  • Create Tkinter widgets and callbacks
  • Embed Turtle in a Canvas
  • Translate logical coordinates
  • Render confirmed state only
  • Understand the Tk event loop
  • Organise presentation code

1. Two libraries, two roles

Tkinter owns the application window, controls, labels, keyboard events and main event loop. Turtle provides a convenient visual actor with a position, orientation and shape. They work together, but neither should own the simulation rules.

The world says “Adam is at (4, 4)”. The presentation layer converts that cell into screen coordinates and asks Turtle to draw there. If a move is rejected, the visual marker must remain where the confirmed state says it is.

01User inputKey or button
02ControllerBuilds an intent
03EngineValidates rules
04RendererDraws the result

2. Build the application shell

  • tk.Tk() creates the main window.
  • ttk.Frame groups controls and layout responsibilities.
  • tk.Canvas becomes the drawing surface.
  • ttk.Label displays tick, position and status.
  • ttk.Button(command=...) registers a callback.
  • root.mainloop() processes UI events and should normally run once.
ENVIRONMENT NOTE

Tkinter and Turtle are part of Python's standard library; they are not normally installed with pip. Some Linux distributions require a system Tk package, and a headless server cannot display the window directly.

3. Embed Turtle explicitly

A plain turtle.Turtle() may create its own global window. In an application, use TurtleScreen(canvas) and RawTurtle(screen) so Tkinter remains the explicit owner of the UI.

import tkinter as tk from tkinter import ttk from turtle import RawTurtle, TurtleScreen WORLD_SIZE = 10 CELL_SIZE = 40 def world_to_turtle(x: int, y: int) -> tuple[float, float]: """Return the centre of a logical cell in Turtle coordinates.""" px = (x + 0.5 - WORLD_SIZE / 2) * CELL_SIZE py = (WORLD_SIZE / 2 - y - 0.5) * CELL_SIZE return px, py root = tk.Tk() canvas = tk.Canvas(root, width=400, height=400, bg="#eef5f0") canvas.pack() screen = TurtleScreen(canvas) screen.tracer(0) adam = RawTurtle(screen) adam.penup() adam.goto(*world_to_turtle(4, 4)) screen.update() root.mainloop()

4. Reconcile coordinate systems

The domain uses top-left origin and positive y downwards. Turtle normally centres the origin and treats positive y as upwards. The conversion function is presentation logic. Keep it outside World so grid tests never depend on pixels.

DOMAIN(0, 0) top-left10 × 10 cells
TRANSFORMCell → centreOffset and invert y
VIEW(0, 0) centredPositive y upwards

5. Respect the event loop

A callback must finish quickly so Tkinter can process repainting, keyboard input and window events. Avoid while True, time.sleep() and direct Ollama calls inside a button handler. Use root.after() for scheduled UI work; Chapter 03 introduces the async worker for slow operations.

6. Guided laboratory

EXPERIMENT A

Render the grid

Draw a 10 × 10 board and keep logical dimensions separate from pixel size.

EXPERIMENT B

Add controls

Four buttons produce movement intentions; none updates Turtle directly.

EXPERIMENT C

Display state

Show tick, position and the latest confirmed event.

EXPERIMENT D

Test the boundary

Attempt an invalid move and verify that World and Turtle remain aligned.

Protocol completion

The window can open and close cleanly, Adam appears in the correct logical cell, an invalid action leaves the marker in place and the domain module imports no GUI library.