[Tkinter-discuss] Canvas -> move object and remove previous location

John McMonagle jmcmonagle at velseis.com.au
Tue May 8 01:48:37 CEST 2007


     # move the image by the difference between the last point
Teresa Stanton wrote:
> Hi all:
>  
> I am working on a program that will take a .gif and move it from origin, 
> along a path where the mouse clicks.  I understand that the move is 
> simply changing the coordinates.  I can place several .gif's on the 
> canvas, but I would like to make the previous image go away (delete or 
> be removed) and thus far been unable to do that. The example program I 
> wrote simply takes the image and moves it.  I should mention that I've 
> tried 'move() and coord()' to get the object to move, but I am not 
> getting the effect I want.  When I use move in successive steps it just 
> appears at the last move coordinates.  And when I try to use delete, 
> well, it doesn't work, I get an error message.  I should mention that 
> I'm using python25.
>  
>  
Ok.  You need to understand some of the Canvas methods better.

Firstly the canvasx and canvasy methods translate screen coordinates 
from your event to the Canvas coordinates.  So when you generate a 
Button-1 event, the event.x and event.y attributes need to be converted 
to your Canvas x and y coordinates.

x2 = canvas1.canvasx(event.x)
y2 =  canvas1.canvasy(event.y)

Second, you need to know what the coordinates are of your canvas image 
object.  This is where the coords method of the Canvas widget will help 
you.  But before you get the coordinates you need to know the object tag 
or id.  The easiest way to do this is to use the tags option when first 
creating the tag.

canvas1.create_image(x,y, image=photo, tags='myPhoto')

Now, you can get the coordinates of this tag:

x1, y1 = canvas1.coords('myPhoto')

Thirdly, the move method of the Canvas widget moves the tag or id dx, dy 
canvas units - it is a differential move.  You could simply move the 
image to the new coordinates by computing the difference between the 
original x,y and the new x,y (as clicked):

canvas1.move('myPhoto', x2-x1, y2-y1)

However, you want to move the image to the clicked point in slow steps. 
  So, this will require you computing a stepped difference between the 
two points, loop over the steps, moving the image, sleeping, then updating.

Fourthly, the delete method of the Canvas widget deletes an item or tag 
(but you don't need it here).

canvas1.delete('myPhoto')

The following code is pretty rough, but should illustrate some of the 
concepts needed.  It also doesn't handle the zero increment case.

from Tkinter import *
import time

root = Tk()
root.title("Click me!")

def next_image(event):
     # Convert the screen coordinates of the event to canvas coordinates
     x2 = canvas1.canvasx(event.x)
     y2 = canvas1.canvasy(event.y)
     x2 = int(x2)
     y2 = int(y2)

     # get the phot object coordinates
     x1, y1 = canvas1.coords('myPhoto')
     x1 = int(x1)
     y1 = int(y1)

     # create two lists of stepped x and y
     xinc = (x2 - x1)/100
     yinc = (y2 - y1)/100
     print xinc, yinc
     xlist = []
     for x in xrange(x1, x2+xinc, xinc):
         print x
         xlist.append(x)
     ylist = []
     for y in xrange(y1, y2+yinc, yinc):
         print y
         ylist.append(y)

     # move the image by the difference between the last point, sleep
     # for half a millisecond, update the display
     for i, x in enumerate(xlist):
         if i == 0:
             canvas1.move('myPhoto', x-x1, ylist[i]-y1)
         else:
             canvas1.move('myPhoto', x-xlist[i-1], ylist[i]-ylist[i-1])
         time.sleep(0.05)
         root.update()

image = "DustY1.GIF" # use any gif, this is a cartoon of my dog
photo = PhotoImage(file=image)

# make canvas the size of image1/photo1
width1 = photo.width()
height1 = photo.height()
canvas1 = Canvas(width=width1, height=height1)
canvas1.pack()

# display photo, x, y is center
x = (width1)/2.0
y = (height1)/2.0
# this is the first image
canvas1.create_image(x, y, image=photo, tags='myPhoto')  # added tags option

canvas1.bind('<Button-1>', next_image)  # bind left mouse click

root.mainloop()


Regards,

John


More information about the Tkinter-discuss mailing list