Reputation: 314
My goal is to write a program, that inserts an object (for example a rectangle)
that can be moved after insertion by using the arrow keys.
I am able to place a rectangle on a canvas, but I can't interact with the
rectangle, because I cannot return a Widget from an event function.
So in this program I can move the rectangle that is already on the canvas,
but when I insert another rectangle I am still moving the first rectangle.
from tkinter import *
root = Tk()
my_canvas = Canvas(root, width = 500, height = 500, bg = "white")
my_canvas.grid(row = 0, column = 0)
my_object = my_canvas.create_rectangle(50, 150, 250, 50, fill = "red")
def left(event):
my_canvas.move(my_object, -10, 0)
def right(event):
my_canvas.move(my_object, 10, 0)
def up(event):
my_canvas.move(my_object, 0, -10)
def down(event):
my_canvas.move(my_object, 0, 10)
def opamp(event):
#the following code does not overwrite my_object...
my_object = my_canvas.create_rectangle(100, 200, 250, 50, fill = "black")
my_label = Label(root, text = "your mouse is at " + str(event.x) + " " + str(event.y))
my_label.grid(row = 1, column = 1)
#returning my_object does not work either
root.bind("<Left>", left)
root.bind("<Right>", right)
root.bind("<Up>", up)
root.bind("<Down>", down)
root.bind("<o>", opamp)
root.mainloop()
Upvotes: 0
Views: 249
Reputation: 47193
You can use tag
instead of item ID returned by .create_rectangle()
in the movement functions:
from tkinter import *
ACTIVE = "active" # tag name for the *active* item
root = Tk()
my_canvas = Canvas(root, width=500, height=500, bg="white")
my_canvas.grid(row=0, column=0)
my_canvas.create_rectangle(50, 150, 250, 50, fill="red", tag=ACTIVE) # make it *active*
def left(event):
my_canvas.move(ACTIVE, -10, 0)
def right(event):
my_canvas.move(ACTIVE, 10, 0)
def up(event):
my_canvas.move(ACTIVE, 0, -10)
def down(event):
my_canvas.move(ACTIVE, 0, 10)
def opamp(event):
my_canvas.dtag(ACTIVE, ACTIVE) # clear current active tag
my_canvas.create_rectangle(100, 200, 250, 50, fill="black", tag=ACTIVE) # make it *active*
#my_label = Label(root, text=f"your mouse is at {event.x} {event.y}")
#my_label.grid(row=1, column=0)
root.bind("<Left>", left)
root.bind("<Right>", right)
root.bind("<Up>", up)
root.bind("<Down>", down)
root.bind("<o>", opamp)
root.mainloop()
Upvotes: 1