Reputation: 15236
UPDATE: This seams to be a version issue. The event does not fire on click for python 3.6.1 but works on 2.7 that I have tested so far.
UPDATE: Bryan's answer did fix my problem with the event not working correctly however the issue of the event not firing on the down-click not work is still an issue on my 3.6.1 version of python.
Python version = 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)]
I am trying to write an event handler to do something repeatedly while the mouse button is being held down. I have been scouring the documentation and the internet but I cannot find any reference to just holding down the left mouse button.
Is there an event specifically for holding down the left mouse button? There is an even for release <ButtonRelease-1>
but there does not seam to be one for a click and hold event.
I have tried <Button-1>
and all of its synonymous events just in case but no luck. The event only fires on release but not on the down click as I want it. I don't even need an event for constantly holding the button I just need an even for the down press only.
Documentation welcome as I can't seam to find any.
UPDATE:
Here is an example code. It will only print when the button is released. Keep in mind I am trying to press the arrow buttons on the scroll bar and to change the speed of scrolling.
Does the scrollbar handle pressing the scroll arrows differently than a button?
import tkinter as tk
root = tk.Tk()
textbox = tk.Text(root, height = 10)
textbox.grid(row=0, column=0)
scrolling = False
yscroll = tk.Scrollbar(root, command=textbox.yview,orient="vertical", repeatinterval=10, repeatdelay=30)
textbox.configure(yscrollcommand = yscroll.set)
yscroll.grid(row=0, column=1, sticky="ns")
for i in range(1000):
textbox.insert(tk.END, "{}\n".format(i))
def scrolling_active(arrow):
global scrolling
root.bind('<ButtonRelease-1>', stop_scrolling())
print(arrow)
if scrolling == True:
if arrow == "arrow1":
textbox.tk.call(textbox._w,'yview', 'scroll', -100, 'units')
if arrow == "arrow2":
textbox.tk.call(textbox._w,'yview', 'scroll', 100, 'units')
root.after(100, lambda a = arrow: scrolling_active(a))
def start_scrolling(event):
global scrolling
scrolling = True
scrolling_active(yscroll.identify(event.x, event.y))
def stop_scrolling():
global scrolling
scrolling = False
yscroll.bind("<Button-1>", start_scrolling)
root.mainloop()
Upvotes: 2
Views: 6240
Reputation: 386342
There is no event for holding a button down. There are only events for the press and release of a button.
If you need to track while a button is down, you can set a flag on the press and unset it on a release.
In your code, you have a bug. Consider this code:
root.bind('<ButtonRelease-1>', stop_scrolling())
It is functionally identical to this:
result=stop_scrolling()
root.bind('<ButtonRelease-1>', None)
To do the binding you must remove the ()
:
root.bind('<ButtonRelease-1>', stop_scrolling)
You also need stop_scrolling
to accept the event object:
def stop_scrolling(event):
global scrolling
scrolling = False
Also, there's no need to call textbox.tk.call
. You can call the yview
method on the tkinter object (textbox.yview("scroll", -100, "units"
)
Upvotes: 1
Reputation: 113
I know it's a bit late, but I wanted to do the exact same thing (drag an image in a canvas to make a joystick controller).
Reading the docs Events and Bindings I found this event: '<B1-Motion>'
Here's the working example I did :
from tkinter import *
root = Tk()
root.geometry('800x600')
image1 = PhotoImage(file = 'images/button.png')
x_img,y_img = 250,250
canvas = Canvas(root, width = 500, height = 400, bg = 'white')
canvas.pack()
imageFinal = canvas.create_image(x_img, y_img, image = image1)
def move(event):
global x_img,y_img
x, y = event.x, event.y
print('{}, {}'.format(x, y))
canvas.move(imageFinal, x-x_img,y-y_img)
x_img = x
y_img = y
canvas.update()
canvas.bind('<B1-Motion>', move)
root.mainloop()
Upvotes: 1
Reputation: 1857
You should be able to bind to <ButtonPress-1>
for when the Mouse is initially clicked, and then call a repeating function until <ButtonRelease-1>
stops it, as you mentioned.
Upvotes: 0