Intro: Tk
One of the most common libraries to create graphics in Python is called Tk (short for "tkinter"). Tk is a powerful graphics library that should be automatically installed for Windows and Mac along with Python when you installed it. While Tk's great, some of the functions are hard to use. For this reason, we provide our own small graphics library that is built on top of Tk and makes it easier to use. It's not a replacement for Tk - it just adds a few new functions to make certain things like drawing text easier. You can always explore the full Tk library if you're interested in seeing what else you can do!
While any graphics projects we create for you will have the necessary graphics files included, you can also
download this graphics file, unzip it, and
add graphics.py
to your project folder if you're starting from scratch.
Then, all you need to do is add from graphics import Canvas
to the top of your code.
Importing
To use our graphics library, you must first import it at the top of your program, by adding this line of code to the top of your file:
from graphics import Canvas
The Canvas
The drawing model for the graphics library is a "canvas" (much like a painting) where you are going to draw various shapes. The canvas is a grid of pixels that have x and y values. The coordinate (0, 0) is in the upper-left-hand corner of the canvas. The values of x increase as you move to the right. The values of y increase as you move down. In other words, you can think of the canvas as follows:
When we want to draw shapes on a canvas, we call functions on that canvas that “create” the shape
we want to draw. These shapes then appear on the canvas. We will generally provide the code that
creates the canvas for you, so all you need to worry about is adding shapes to that canvas. For the
remainder of this handout, we will assume that a variable named canvas
has already been created,
and it represents the canvas that you'll be drawing on. Usually this will be done with the following
provided code:
# create a new canvas
canvas = Canvas()
# get the width and height of our canvas, in pixels
canvas_width = canvas.get_width()
canvas_height = canvas.get_height()
# call this at the end of the program to make the window show
canvas.mainloop()
When we create the canvas, we can optionally specify its width and height, as well as a title that will appear at the top of the canvas window. For example, to make a canvas that's 800 pixels wide and 200 pixels tall, with the title 'My Canvas', you would do the following:
canvas = Canvas(800, 200, 'My Canvas')
Below we provide a brief tour of some of the different shapes you can draw on a canvas as well as highlight a few of the options you have with regard to how those shapes look.
Drawing Lines
To draw lines on the canvas, use create_line
and specify the coordinates for the start and end points
of the line and the line's color as a string. For example, the following command would draw a black line from
location (10, 20) to (100, 50) on the canvas:
canvas.create_line(10, 20, 100, 50, 'black')
By default, all lines are drawn in black if you omit the color parameter.
Drawing Rectangles
To draw a rectangle on the canvas, use create_rectangle
and specify the coordinates for the top left corner and
bottom right corner of the rectangle, as well as a color as a string. For example, the following command would draw a yellow
rectangle with upper left-hand corner at (5, 50) and lower right-hand corner at (100, 200) on the canvas:
canvas.create_rectangle(5, 50, 100, 200, 'yellow')
By default, all rectangles are drawn in black if you omit the color parameter.
Drawing Ovals
To draw an oval on the canvas, use create_oval
and specify the coordinates for the top left corner
and bottom right corner of the bounding box containing the oval you would like to draw. In other words, the oval
drawn will have its top, bottom, right, and left just touching the sides of the bounding box you specify. You'll also
specify a color as in the previous functions. For example, the following command would draw a red oval that fits
within an imaginary rectangle with upper left-hand corner at
(5, 50) and lower right-hand corner at (100, 200) on the canvas:
canvas.create_oval(5, 50, 100, 200, 'red')
Here's what this code would draw on the canvas - note that we can think of this as an imaginary bounding box from (5, 50) to (100, 200), with an oval drawn inside it:
By default, all ovals are drawn in black if you omit the color parameter.
To make clear the notion of a bounding box, below we draw the same red oval and yellow rectangle from before, where both the oval and rectangle have the same coordinates. Notice how the rectangle is like a bounding box around the oval with the same coordinates.
canvas.create_rectangle(5, 50, 100, 200, 'yellow')
canvas.create_oval(5, 50, 100, 200, 'red')
Drawing Text
To draw text on the canvas, use create_text
to specify an x and y coordinate, and the following parameters:
- anchor
- font
- text
- color (optional, defaults to black)
The anchor is a string, one of "n", "ne", "e", "se", "s", "sw", "w", "nw", or "center"
, that describes
what side of your text you want to position at the (x, y) you provide. Font describes the style and size of the text,
for example 'Helvetica 32'. The text is the text string you want to appear on the screen. Here's a sample call
of create_text
with all of the necessary parameters (this is all one line, we've just split it to fit
on the page):
canvas.create_text(50, 50, anchor='w', font='Arial 50', text='My first text!', color='blue')
Adding Images
You can add image files to your canvas as well. To do this, use create_image
(if you want the image
to be the same size on the canvas as the image file) or create_image_with_size
(if you want the image
to be another size you specify). Both require you to specify the x and y location of the upper-left corner of the
image on the canvas, as well as the name of the image file. create_image_with_size
also requires a
width and a height that the image should be. Here's an example that adds a smiley-face image to the canvas with
upper-left corner at (25, 30), assuming we have an image file named "smiley.jpg" in our PyCharm project:
# create image with default dimensions
canvas.create_image(25, 30, 'smiley.png')
# or add with specific dimensions width = 100, height = 300
canvas.create_image_with_size(25, 30, 100, 300, 'smiley.png')
Here's what this code would draw on the canvas - note that the larger smiley is the one from
the create_image
call (the original image was 216 by 216 pixels), and the distorted one is the
100x300 smiley drawn with create_image_with_size
:
One note about Tk images is that they cannot be resized after you create them.
Note: If images do not work in your program and you're getting an error, you may
not have installed the library necessary for images to work. Make sure you've installed the necessary library by
running python3 -m pip install Pillow
in your terminal (use py
or python
instead
of python3
if you're on Windows).
Removing Objects From the Canvas
You can remove objects from the canvas using delete
:
rect = canvas.create_rectangle(100, 200, 300, 400, 'yellow')
...
canvas.delete(rect)
Note that deleting an object is permanent - if you want to temporarily make an object hidden,
use set_hidden
. You can pass in either True
or False
to set an object
to be hidden or visible:
rect = canvas.create_rectangle(100, 200, 300, 400, 'yellow')
canvas.set_hidden(rect, True) # no longer visible
...
canvas.set_hidden(rect, False) # visible again
Object Ordering
Objects are drawn on the canvas in the order in which they are created by your code. So, if you draw a red rectangle after a yellow circle, the red rectangle can potentially cover (occlude) part of the yellow circle. This is sometimes referred to as the z-order of the objects.
As an example, below, we first draw a yellow rectangle, then draw an orange oval (which partly overlaps the rectangle), and then some text (that is on top of both the rectangle and the oval).
canvas.create_rectangle(10, 50, 200, 300, 'yellow')
canvas.create_oval(100, 100, 300, 350, 'red')
canvas.create_text(70, 170, anchor='sw', font='Arial 30', text='yay!')
Changing Object Colors
Sometimes, we'll want to refer to an object after we've created it, like when we want to change an object's
color later in the program. In that case, it's a good idea to store that object in a variable for us to use later.
If we know we'll want to change the color of a rectangle after we've created it, we might store that object
in a variable called rect
and use the set_color
function to change its color like this:
rect = canvas.create_rectangle(0, 0, 50, 100, 'yellow')
...
canvas.set_color(rect, 'red')
We can also individually change the outline or fill of an object using
the set_fill_color
and set_outline_color
functions as follows:
rect = canvas.create_rectangle(0, 0, 50, 100, 'yellow')
...
canvas.set_fill_color(rect, 'red')
canvas.set_outline_color(rect, 'blue')
Here's a list of all the colors you can use in Tk.
Getting Information About Objects
For all graphical objects, you can ask the canvas for information about them. For instance, you can get an object's
dimensions via get_obj_width
and get_obj_height
:
rect = canvas.create_rectangle(0, 0, 50, 100, 'yellow')
print(canvas.get_obj_width(rect)) # prints 50
print(canvas.get_obj_height(rect)) # prints 100
You can also ask the canvas for information about an object's location. Specifically, you can get the left-most x coordinate of the object, or the top-most y coordinate as follows:
oval = canvas.create_oval(5, 10, 50, 100, 'red')
print(canvas.get_left_x(oval)) # prints 5
print(canvas.get_top_y(oval)) # prints 10
Note that for something like an oval, the dimensions and left corner are from the bounding box that contains it.
Moving Graphical Objects
You can change the location of an object using moveto
. You specify new x and y coordinates, which will
be the upper-left corner of the bounding box for the object (e.g. bounding box for an oval, bounding box for a line, etc.).
Here's how we would move a rect to have upper-left corner at (25, 50):
rect = canvas.create_rectangle(100, 200, 300, 400, 'yellow')
canvas.moveto(rect, 25, 50) # moves upper left to 25, 50`
You can also change the location of an object by specifying how much you would like to move it by, instead
of specifying the new location. The move
function lets you specify the change in x and the
change in y for the object, relative to its current location. For example, here's how we would move a rectangle
5 pixels to the right, and 10 pixels down:
rect = canvas.create_rectangle(100, 200, 300, 400, 'yellow')
canvas.move(rect, 5, 10) # moves upper left to 105, 210