views:

35

answers:

3

I need a command to be executed as long as the left mouse button is being held down.

+1  A: 

Use the mouse move/motion events and check the modifier flags. The mouse buttons will show up there.

Aaron Digulla
+2  A: 

Look at table 7-1 of the docs. There are events that specify motion while the button is pressed, <B1-Motion>, <B2-Motion> etc.

If you're not talking about a press-and-move event, then you can start doing your activity on <Button-1> and stop doing it when you receive <B1-Release>.

Jesse Dhillon
What does the code for stopping an event look like?
Anteater7171
I would recommend keeping a variable like `mouse_is_down` and set it to `True` or `False` depending on whether or not you receive the press or release event. In your code, during the loop you can check to see if the variable is `True`, meaning the mouse is down, and do your thing for a button hold. When the variable is `False`, you can skip your code for mouse button holding.
Jesse Dhillon
+2  A: 

If you want "something to happen" without any intervening events (ie: without the user moving the mouse or pressing any other buttons) your only choice is to poll. Set a flag when the button is pressed, unset it when released. While polling, check the flag and run your code if its set.

Here's something to illustrate the point:

import Tkinter

class App:
    def __init__(self, root):
        self.root = root
        self.mouse_pressed = False
        f = Tkinter.Frame(width=100, height=100, background="bisque")
        f.pack(padx=100, pady=100)
        f.bind("<ButtonPress-1>", self.OnMouseDown)
        f.bind("<ButtonRelease-1>", self.OnMouseUp)

    def do_work(self):
        x = self.root.winfo_pointerx()
        y = self.root.winfo_pointery()
        print "button is being pressed... %s/%s" % (x, y)

    def OnMouseDown(self, event):
        self.mouse_pressed = True
        self.poll()

    def OnMouseUp(self, event):
        self.root.after_cancel(self.after_id)

    def poll(self):
        if self.mouse_pressed:
            self.do_work()
            self.after_id = self.root.after(250, self.poll)

root=Tkinter.Tk()
app = App(root)
root.mainloop()

However, polling is generally not necessary in a GUI app. You probably only care about what happens while the mouse is pressed and is moving. In that case, instead of the poll function simply bind do_work to a <B1-Motion> event.

Bryan Oakley