Home > Software design >  How can I detect long mouse clicks with tkinter?
How can I detect long mouse clicks with tkinter?

Time:05-15

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:

screenshot of it running

  • Related