I am working on a script that will listen to keystrokes till the 'q' button is pressed, afterwards it should stop the script and print out the mouse positions that were saved in 2 seconds intervals. I can't manage the threads and I am still learning this topic. Each time I run the code nothing happens but the process is running:
from pynput.keyboard import Listener
import pyautogui
from multiprocessing import Process
import time
mouse_positions = []
def func1():
while True:
time.sleep(2)
mouse_positions.append(pyautogui.position())
cordinates = []
quit_status = False
keystrokes = []
def on_press(key):
if "q" in str(key) :
print('q was pressed!')
exit("Stopped running")
#qprint(key)
keystrokes.append(key)
print(keystrokes)
#print(keystrokes)
if __name__ == '__main__':
p1 = Process(target=func1)
p1.start()
p1.join()
with Listener(on_press=on_press) as listener: # Create an instance of Listener
listener.join() # Join the listener thread to the main thread to keep waiting for keys
EDIT : To anyone intrested, here is a click macro I built, script I built previously was more like mouse capture movement. The script below will record your mouse clicks and afterwards will replay them. Much better.
from pynput.keyboard import Listener
import pyautogui
from pynput import mouse
import time
x_pos = []
y_pos = []
both_pos = []
pressed_key = None
def on_click(x, y, button, pressed):
if pressed:
#print ("{0} {1}".format(x,y))
print(pressed_key)
if pressed_key == "1":
both_pos.append("{0}".format(x,y))
both_pos.append("{1}".format(x,y))
#print("test" + x_pos + y_pos)
print (x_pos + y_pos)
else:
pass
if pressed_key == 'q':
return False
def on_press(key):
print("To replay press 'q' , to stop recording press '1' , to record again press '1' .")
global pressed_key
if 'Key.esc' in str(key):
return False
if '1' in str(key):
pressed_key= None if pressed_key == '1' else '1'
if 'q' in str(key):
print("Replaying actions")
print(str(len(both_pos)))
for point in range(0,len(both_pos),2):
time.sleep(3)
print("clicking")
pyautogui.click(x=int(both_pos[point]),y=int(both_pos[point+1]))
print("done...")
return False
mouse_listener = mouse.Listener(on_click=on_click)
mouse_listener.start()
with Listener(on_press=on_press) as listener: # Create an instance of Listener
listener.join()
#print(mouse_listener.mouse_positions)
Hi you can use threading
module.
I have created class MouseListener
which inherit from threading.Thread
class. Everything what you want to run put into run
method. As thread stopper I used still_run
attribute.
When you are typing, I pass to on_press
function pressed key and mouse_listener
. If q is pressed I set mouse_listener.still_run
to False
, what leads to stop the mouse listener.
mouse_positions
I moved from global scope to MouseListener
.
import threading
from pynput.keyboard import Listener
import pyautogui
import time
class MouseListener(threading.Thread):
still_run = True
mouse_positions = []
def run(self):
self.func()
def func(self):
while self.still_run:
time.sleep(2)
self.mouse_positions.append(pyautogui.position())
print(self.mouse_positions)
coordinates = []
quit_status = False
keystrokes = []
def on_press(key, mouse_listener):
print('kp')
if "q" in str(key):
print('q was pressed!')
mouse_listener.still_run = False
print(key)
exit("Stopped running")
keystrokes.append(key)
print(keystrokes)
print(keystrokes)
if __name__ == '__main__':
mouse_listener = MouseListener()
mouse_listener.start()
with Listener(on_press=lambda key: on_press(key, mouse_listener)) as listener: # Create an instance of Listener
listener.join()
print(mouse_listener.mouse_positions)