Python: Jak w pynput uruchamiać funkcję tylko raz pomimo wielokrotnego klikania myszą gdy funcja już jest uruchomiona?
Jeśli będzie używał Listener
do uruchamia w głównym wątku długo trwającego kodu
wtedy będzie on blokował listener i nie będzie on mógł wykonywac innego kodu.
Listener nie będzie mógł także odbierać od systemu zdarzeń i będą one czekały w kolejne
i listener odbierze je później i zdarzenia te mogą uruchomić kod długo po kliknięciu zamiast pominąć te zdarzenia.
Niepoprawna wersja.
Gdy klikniesz przycisk myszy to do_work
zostanie uruchomiony w obecnym wątku i to spowoduje zablokowanie listener'a
i w ten sposób listener nie będzie mógł pobierać innych zdarzeń i nie będzie mógł pomimać innych kliknięć podczas wykonywania do_work
.
Listener otrzyma te kliknięcia po zakończeniu do_work
(ale nie będzie wiedział, że te kliknięcia zostały wykonane w przeszłości) i będzie uruchamiał kod choć nie powinien tego robić.
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()
Poprawna wersja.
Gdy klikniesz przycisk myszy to do_work
zostanie uruchomiony w osobnym wątku i nie będzie zablokować listener'a
i w ten sposób listener będzie mógl pobierać inne zdarzenia i pomijać kliknięcia podczas wykonywania do_work
.
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()