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.
2. Build the application shell
tk.Tk()creates the main window.ttk.Framegroups controls and layout responsibilities.tk.Canvasbecomes the drawing surface.ttk.Labeldisplays tick, position and status.ttk.Button(command=...)registers a callback.root.mainloop()processes UI events and should normally run once.
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.
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
Render the grid
Draw a 10 × 10 board and keep logical dimensions separate from pixel size.
Add controls
Four buttons produce movement intentions; none updates Turtle directly.
Display state
Show tick, position and the latest confirmed event.
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.