[Tkinter-discuss] How to bind to a drawn object?

Guilherme Polo ggpolo at gmail.com
Sun Nov 16 18:57:39 CET 2008

On Sun, Nov 16, 2008 at 3:47 PM,  <btkuhn at email.unc.edu> wrote:
> Hello everyone,
> I am trying to create bindable shapes with Tkinter that are dragged when the
> user drags with the mouse. Here is an example (some code edited out for
> simplicity). This is all within an "App" class:
> self.canvas=Canvas(self.display, bg='blue')
> self.canvas.bind('<B1-Motion>', self.onDrag)
> self.x=10
> self.y=10
> #Draw ball, set up screen layout
>            self.box1=self.drawBox(self.canvas)
>       self.canvas.pack()
>          def drawBox(self,master):
>       newbox=master.create_rectangle(self.x, self.y, self.x+70, self.y+70,
> width=5, fill='red')
>              return newbox
>      def onDrag(self,event):
>       self.canvas.move(self.box1,event.x-self.x,event.y-self.y)
>       self.x=event.x
>       self.y=event.y
> This works as written, but it is not good form because it can only be used
> with box1. <B1-Motion> is bound to the canvas rather that the box, and
> "self.box1" is explicitly stated in the onDrag method. Therefore, if I
> wanted to create 10 boxes (or even 2) I would have to write a new onDrag
> method for each one. Also, if I want the box to only drag when the user
> clicks INSIDE the box, I would have to create a new "dimensions" list for
> each new box, and then use an if statement to see if the mouse is inside the
> box, etc. I actually tried doing this and it makes the program run extremely
> slow with only one box, so I don't think this is a good solution. It seems
> logical to bind <B1-Motion> to box1 rather than the canvas, and that way the
> box will react only if the mouse is inside the box, and I could create
> multiple boxes, each with its own binding to <B1-Motion>. When I try to do
> this, though, using something like this:
> newbox=master.create_rectangle(self.x, self.y, self.x+70, self.y+70,
> width=5, fill='red')
> newbox.bind('<B1-Motion>', self.onDrag)
> it gives me an error saying that I can't bind this method to this instance.

Didn't you mean an AttributeError ? The id returned my
create_rectangle surely doesn't have a bind method.

> How can I make this work?

That is why Canvas has a method called tag_bind, to bind an item in the canvas:

master.tag_bind(newbox, '<B1-Motion>', self.on_drag)

> Thanks!
> _______________________________________________
> Tkinter-discuss mailing list
> Tkinter-discuss at python.org
> http://mail.python.org/mailman/listinfo/tkinter-discuss

-- Guilherme H. Polo Goncalves

More information about the Tkinter-discuss mailing list