Python: How in pynput runs function only once when you click many times and function is already running?
If you will use Listener
to run long-running code directly in current thread
then it will block listener and listener will not execute other code.
Listener will also not get mouse events from system and these events will wait in queue and listener will get them later and it will execute code long after clicks (but it should skip these events)
Wrong version.
When you click button then it runs do_work
in current thread and it will blocks listener
and this way listener may not get other events and it can't skip clicks when do_work
is still working.
It will get these clicks later (but it will not know that these clicks are from past and it should skip them) and it will execute code again.
from pynput import mouse
import time
# --- functions ---
def do_work(x, y, button, pressed):
if pressed:
# emulate long-running process
print("Started work.")
time.sleep(3)
print("Finished work.")
# --- main ---
with mouse.Listener(on_click=do_work) as listener:
# ... other code ...
listener.join()
Correct version.
When you click button then it runs do_work
in separted thread and it will not block listener
and this way listener may get other events and skip clicks when do_work
is still working.
If you assing thread to global variable then you can control if it still running - and you can run it again only when it is not running at this moment.
from pynput import mouse
import threading
import time
# --- functions ---
def do_work(x, y, button, pressed):
# emulate long-running process
print("Started work.")
time.sleep(3)
print("Finished work.")
def on_click(x, y, button, pressed):
global job
if pressed:
if job is None or not job.is_alive():
job = threading.Thread(target=do_work, args=(x, y, button, pressed))
job.start()
#else:
# print("skiping this click")
# --- main ---
job = None # default value at start
with mouse.Listener(on_click=on_click) as listener:
# ... other code ...
listener.join()
Buy a Coffee