Creating The Python UI With Tkinter - The Canvas Widget
Written by Mike James   
Thursday, 23 April 2020
Article Index
Creating The Python UI With Tkinter - The Canvas Widget
Shapes
Co-ordinates

Bounce the ball

This suggests a simple example bouncing a small rectangular ball around the canvas. The only new idea we need is some way of executing the move function after a regular time interval. You could do this using the thread sleep but this has problems in that used in the simplest way it freezes the UI.

A much better solution is to use the root window's after method. The call

root.after(ms,function)

will call the function after ms milliseconds.It does this using the event queue so the UI stays active during the wait.

If you need to pass some arguments to the function use:

root.after(ms,function,args)

To call a function periodically you simply have to add the call to the end of the function so that it adds itself to the event queue:

def move():
    global Dx,Dy
    x1,y1,x2,y2=w.coords(id1)
    if x1+Dx<=0 or x1+Dx>=190:
        Dx=-Dx
    if y1+Dy<=0 or y1+Dy>=190:
        Dy=-Dy
    w.coords(id1,x1+Dx,y1+Dy,x2+Dx,y2+Dy)
    root.after(50,move)

 

The main program is:

root=Tk()
w = Canvas(root, width=200, height=200,
           borderwidth=0,
           highlightthickness=0,
           background='white')
w.pack(padx=10,pady=10)
Dx=1
Dy=1
id1=w.create_rectangle(3,7,3+10,7+10)
root.after(50,move)

root.mainloop()

There are better ways to organize a program like this but this is the main idea.

Notice that Dx and Dy play the role of velocities and when the ball reached the edge of the canvas these are simply reversed to provide a bounce. 

 

bounce

 

It you try it out then you will find that it isn't the smoothest animation ever but it works and it demonstrates the idea of the canvas being a retained mode vector graphics system. Notice that you don't have to blank out the old ball position because the canvas does the redraw for you.

Add a couple of bats and a net and you have Python Pong...

Shapes

Now that you have met the rectangle and seen how it works it is easy to figure out how to use the other drawing methods:

  • create_arc(bbox, options)
  • create_bitmap(position, options)
  • create_image(position, options)
  • create_line(coords, options)
  • create_oval(bbox, options)
  • create_polygon(coords, options)
  • create_rectangle(bbox, options)
  • create_text(position, options)
  • create_window(position, options)

All of these do what you expect them to do from their name and they all return an object Id so that you can continue to work with the graphic object you have created. You need to lookup the options that can be used with each of the graphics objects but apart from this it is all - as for the rectangle.

For example to replace the rectangle with a circle you would use:

id1=w.create_oval(3,7,3+10,7+10)

Some of the methods have quite complicated lists of options but if you look them up you should be able to work out how to draw what you need.

The only method that might need some explanation is  create_window. This allows you to put any existing widget on a canvas. For example,

button1=Button(root,text='Move')
w.create_window(20,20,window=button1)

This allows you to mix widgets with general graphics. You can only place one widget into each window object. use a frame if you want to add a group of widgets in a single window.

Text on a canvas is easy enough:

w.create_text(50,20,text="hello canvas")

the only complication is that the location is the center of the text not the top corner. Working with text in a canvas can become complicated if you are going to allow the user to interact with it. Working with text is the subject of another article.



Last Updated ( Thursday, 23 April 2020 )