I want to detect a long mouse click using tkinter.
How can I do that?
The <Button-1>
doesn't help at all.
CodePudding user response:
You can create a binding for both the button press (<ButtonPress-1>
) and button release (<ButtonRelease-1>
). Save the time that the press happened and then compute the delay when the release happened.
Or, depending on what you mean by "detect", you can schedule a job to run when the button is clicked, and then cancel the job if the button is released before the timeout.
CodePudding user response:
Here's code demonstrating how to "detect" when a long mouse click has occurred (the second thing @Bryan Oakley mentioned). It accomplished the feat by "binding" various callback functions to different tkinter
events, including a virtual one I made up named '<<LongClick-1>>'
.
It will display a window with a Label
in it indicating the mouse's click status. If you click and hold the mouse button down long enough (2 secs), the on_long_click()
event handler function will called and change the text on the Label
accordingly.
import tkinter as tk
from tkinter.constants import *
from time import perf_counter as cur_time
LONG_CLICK = 2.0 # Seconds.
start_time = None
timer = None
CHECKS_PER_SECOND = 100 # Frequency that a check for a long click is made.
root = tk.Tk()
root.geometry('100x100')
def on_button_down(event):
global start_time, timer
label.config(text='Click detected')
start_time = cur_time()
timing = True
timer = check_time()
def check_time():
global timer
if (cur_time() - start_time) < LONG_CLICK:
delay = 1000 // CHECKS_PER_SECOND # Determine millisecond delay.
timer = root.after(delay, check_time) # Check again after delay.
else:
root.event_generate('<<LongClick-1>>')
root.after_cancel(timer)
timer = None
def on_button_up(event):
global timer
if timer:
root.after_cancel(timer)
timer = None
label.config(text='Waiting')
def on_long_click(event):
label.config(text='Long click detected')
label = tk.Label(root, text='Waiting')
label.pack(fill=BOTH, expand=1)
root.bind('<ButtonPress-1>', on_button_down)
root.bind('<ButtonRelease-1>', on_button_up)
root.bind('<<LongClick-1>>', on_long_click)
root.mainloop()
Although it's not particularly exciting, here's a screenshot of it running: