I realize this question has been asked many times but I have a very difficult time understanding threading and with statement and consequently I cannot understand the other answers given. I was able to accomplish this task about 5 years ago but my threading skills have since fallen into disuse. In any case, I'm trying to register the x,y coordinates of a mouse click, store the values to a global, then terminate the keyboard listener, then do other things. In the code below, I cannot get the code to advance to where it says p("done")
, even after I press the 'e' button. When I pause the code and analyse the values of the done
variable it will output 1 so I don't understand why the code is not advancing to the next line. Again, I want to iterate to please not assume that I understand what you're saying when you talk about threading
or with
statements. I have only a very vague notion of what these things do.
from pynput import keyboard, mouse
done = 0
xa = 0
ya = 0
p = print
def on_click(x, y, button, pressed):
global xa, ya
print (x,y)
xa = x
ya = y
def on_press(key):
global done
if key.char == 'e':
done = 1
def listen():
global done
with keyboard.Listener(on_press=on_press) as kl, \
mouse.Listener(on_click=on_click) as ml:
kl.join()
ml.join()
while 1:
if done:
p ('done')
kl.terminate()
ml.terminate()
p ('you did it')
return
Quick research: There should be stop conditions in mouse's on_click
and keyboard's on_release
. on_release
is not presented in your example but the keyboard listener needs it implemented to accurately stop listening.
I've changed the example a bit. Notice the lines where I put the comment "# Stop listener". They are simply a branching statement.
from pynput import keyboard, mouse
done = 0
xa = 0
ya = 0
p = print
def on_click(x, y, button, pressed):
global xa, ya
print(x, y)
xa = x
ya = y
if not pressed:
# Stop listener
return False
def on_press(key):
global done
try:
if key.char == "e":
done = 1
except:
pass
def on_release(key):
try:
if key.char == "e":
# Stop listener
return False
except:
pass
def listen():
global done
with keyboard.Listener(on_press=on_press, on_release=on_release) as kl, \
mouse.Listener(on_click=on_click) as ml:
kl.join()
ml.join()
while 1:
if done:
p("done")
kl.stop() # .terminate() is incorrect
ml.stop() # .terminate() is incorrect
p("you did it")
return
listen()