Reputation: 33
I am working on a python program for moving two circles on a canvas with the mousepointer. I have figured out how to attach the motion to the circles, but when I drag it with the mousebutton the circles goes in a weird direction. Their motions should also be separate but now they are entangled.
I have tried to use the built in move-function and e.x and e.y function. Below is my code.
from tkinter import *
class movingCircle:
def __init__(self):
self.window = Tk()
self.window.title("Moving circles")
self.window.geometry("500x400")
self.canvas1 = Canvas(self.window, width = 300, height = 300, bg = "grey")
self.canvas1.pack(pady=30)
self.circle1 = self.canvas1.create_oval(10, 10, 50, 50, fill="red")
self.circle2 = self.canvas1.create_oval(100, 100, 70, 70, fill="red")
self.window.bind("<B1-Motion>", self.move)
self.window.mainloop()
def move(self, event):
self.canvas1.move(self.circle1, event.x, event.y)
self.canvas1.move(self.circle2, event.x, event.y)
movingCircle()
Upvotes: 3
Views: 518
Reputation: 386372
self.canvas1.move
requires a distance, but you're passing a pixel address.
One solution is to remember the previous pixel location, then in your move
function you need to calculate how many pixels the cursor has moved and pass that to self.canvas1.move
.
The other problem is that you are explicitly moving all of the items. If you only want to move the one that was clicked on you can use the tag "current".
In the following example based on your code, notice that there's an extra event binding to save the location where you first click, and this value is then used to compute how far the mouse has moved in each direction. Also notice that it only calls move
for "current" rather than one of the oval ids.
from tkinter import *
class movingCircle:
def __init__(self):
self.window = Tk()
self.window.title("Moving circles")
self.window.geometry("500x400")
self.canvas1 = Canvas(self.window, width = 300, height = 300, bg = "grey")
self.canvas1.pack(pady=30)
self.circle1 = self.canvas1.create_oval(10, 10, 50, 50, fill="red")
self.circle2 = self.canvas1.create_oval(100, 100, 70, 70, fill="red")
self.window.bind("<ButtonPress-1>", self.start_move)
self.window.bind("<B1-Motion>", self.move)
self.window.mainloop()
def start_move(self, event):
self._x = event.x
self._y = event.y
def move(self, event):
deltax = event.x - self._x
deltay = event.y - self._y
self._x = event.x
self._y = event.y
self.canvas1.move("current", deltax, deltay)
movingCircle()
Upvotes: 3