1

I'm trying to bind mouse motions (pressed/unpressed) with some methods. I tried to handle mouse motions while mouse button is pressed with '' and the other with just ''. I found that when I just have ..bind('', somemethod1), somemethod1 is called regardless of mouse button press, but when I also have ..bind('', somemethod2), somemethod1 is not called when mouse button was pressed. Adding 'add='+'' didn't seem to work.

def bind_mouse(self):
    self.canvas.bind('<Button1-Motion>', self.on_button1_motion1)
    self.canvas.bind('<Motion>', self.on_mouse_unpressed_motion1)

def on_button1_motion1(self, event):
    print(self.on_button1_motion1.__name__)

def on_mouse_unpressed_motion1(self, event):
    print(self.on_mouse_unpressed_motion1.__name__)

So I instead modified the on_button1_motion1 method as below:

def on_button1_motion1(self, event):
    print(self.on_button1_motion1.__name__)
    self.canvas.event_generate('<Motion>')

But when I tried this, I got this runtime error:

Traceback (most recent call last): File "D:/save/WORKSHOP/py/tkinter/Blueprints/Pycrosoft Paintk/view.py", line 107, in root.mainloop() File "C:\Users\smj\AppData\Local\Programs\Python\Python35\lib\tkinter__init__.py", line 1131, in mainloop self.tk.mainloop(n) RecursionError: maximum recursion depth exceeded

Can anyone explain to me why this is happening? I know I can solve this problem by just calling on_mouse_unpressed_motion1 method inside on_button1_motion1 method instead of generating an event, but I'd like to know why the other way doesn't work. Thanks

1 Answer 1

1

It creates an infinite loop.

You are listening for <Button1-Motion>, and when you get it, you create more <Motion> while the Button is pressed (because it's only generated when the button-1 event is caught). So you're generating another <Button1-Motion> event. So the function is called again, and so on.

<Motion>

The mouse is moved with a mouse button being held down. To specify the left, middle or right mouse button use <B1-Motion>, <B2-Motion> and <B3-Motion> respectively.

...

From here.

Sign up to request clarification or add additional context in comments.

4 Comments

Hm, so you mean when I create the '<Motion>' event while listening to '<Button1-Motion>' event, on_button1_motion1 gets called because "listening for <Button1-Motion> registers <Motion>"? Interesting. I never knew that.
Does "listening for" mean while the command (method) for that event is being executed (before returning)?
I'm sorry, I made a mistake: '<Motion>' does not always trigger the callback for '<Button1-Motion>'. I recreated your program and found the same behavior. The problem is that generating the '<Motion>' event when the button is already pressed generates another '<Button1-Motion>' event (because the Button is pressed and you're generating Motion!). To your last question: Yes, while you're executing the callback function on_button1_motion1, the widget is still listening for further events, and you're creating another '<Motion>' event, while the Button is pressed, so it is '<Button1-Motion>'.
Thanks. That really helped.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.