The Tk Canvas as a Drawing Surface
The Tk canvas is a general-purpose drawing surface rather than a widget with fixed content: you create it with canvas .c -width 400 -height 300, then populate it by calling create commands such as .c create rectangle or .c create line, each of which returns a unique integer item id you use afterward to modify or query that shape.
Cricket analogy: Like a groundsman rolling out a blank pitch before markings are painted on, an empty canvas widget has no content until you actively draw creases and popping lines with create commands, each one identified by its own id.
Canvas Items and Coordinates
Canvas items span several built-in types — line, rectangle, oval, polygon, arc, text, bitmap, image, and window — each positioned using a pixel coordinate system where (0,0) is the top-left corner and y increases downward; visual options like -fill, -outline, -width, and -stipple control appearance per item type.
Cricket analogy: Choosing between a rectangle, oval, or polygon item is like a scorer choosing between a bar chart, pie chart, or Manhattan chart to represent Virat Kohli's strike rate — each visual type suits different data, and the y-axis convention still has to be respected.
Creating and Configuring Items
After creation you rarely hardcode positions again: .c coords $id x1 y1 x2 y2 repositions an item, .c itemconfigure $id -fill red restyles it, and assigning one or more tags via -tags {ball movable} lets you later select and manipulate whole groups with .c move movable 5 0 instead of touching each id individually.
Cricket analogy: Tagging several canvas items as 'fielders' and moving them together with .c move fielders 10 0 is like a captain shifting the entire off-side field for a left-hander in one instruction rather than repositioning each fielder individually.
package require Tk
canvas .c -width 400 -height 300 -bg white -scrollregion {0 0 800 600}
pack .c -fill both -expand true
# Draw a rectangle and an oval, tag them as "shapes"
set rectId [.c create rectangle 20 20 120 90 -fill lightblue -outline navy -width 2 -tags {shapes rect}]
set ovalId [.c create oval 150 30 230 100 -fill salmon -outline darkred -tags {shapes ball}]
# Bind dragging behavior to any item tagged "shapes"
.c bind shapes <ButtonPress-1> {
set ::dragData(item) [.c find withtag current]
set ::dragData(x) %x
set ::dragData(y) %y
}
.c bind shapes <B1-Motion> {
set dx [expr {%x - $::dragData(x)}]
set dy [expr {%y - $::dragData(y)}]
.c move $::dragData(item) $dx $dy
set ::dragData(x) %x
set ::dragData(y) %y
}
# Restyle an item after the fact
.c itemconfigure $rectId -fill yellowEvent Binding and Tags
Canvas widgets support per-item event binding with .c bind $tag <ButtonPress-1> callback, where the special tag current always refers to whatever item the pointer is over and all matches every item, letting you write one generic handler — for example dragging any shape by binding <B1-Motion> to a group tag shared by draggable items.
Cricket analogy: Binding a callback to the current tag is like a stump microphone that always picks up whichever bowler is currently at the crease — the binding doesn't care which specific item it is, only that it's the active one under the pointer.
The special tag current always refers to whichever item the mouse pointer is presently over, updated automatically by Tk before each event — you rarely need to compute 'which item was clicked' manually; .c find withtag current gives it to you directly.
Scrolling and Performance
For content larger than the visible window, -scrollregion {0 0 2000 2000} combined with .c xview / .c yview (typically wired to a Scrollbar) lets users pan across a virtual drawing area far bigger than the widget; for performance, minimize per-frame itemconfigure calls, use .c bbox for cheap hit-testing instead of scanning all items, and avoid excessive -stipple fills which are costly to render.
Cricket analogy: Setting a scrollregion larger than the visible canvas is like a stadium's giant screen only showing part of the full replay reel — xview/yview let the operator pan across the whole reel without re-rendering it from scratch.
Canvases with several thousand items, heavy -stipple fills, or per-frame full-canvas itemconfigure calls can visibly lag, especially on older X11 backends; batch updates, prefer moving/tagging over recreating items, and consider a background image (create image with a Photo) for static, complex artwork instead of thousands of primitive items.
- The canvas is a blank drawing surface populated by
createcommands, each returning a unique item id. - Item types include line, rectangle, oval, polygon, arc, text, bitmap, image, and window, positioned in a top-left-origin pixel coordinate system.
itemconfigurerestyles an existing item;coordsrepositions it without recreating it.- Tags group items so one call — like
.c move tag dx dy— can affect many items at once. - The
currenttag always refers to the item under the pointer;allmatches every item. -scrollregionplusxview/yviewlets a canvas host content far larger than its visible window.- Performance suffers from excessive per-item updates and heavy stipple fills; use
bboxfor hit-testing and batch changes.
Practice what you learned
1. What does `.c create rectangle 20 20 120 90` return?
2. Which tag always refers to whichever item the mouse pointer is currently over?
3. How do you reposition an existing canvas item without deleting and recreating it?
4. What is the primary performance benefit of using `.c bbox` for hit-testing?
5. What does `-scrollregion {0 0 2000 2000}` configure?
Was this page helpful?
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics