pynput.keyboard terminate program when key is pressed not responding - keyboard

I have this code here and what I want is for the code to type "potato" every 5 seconds. I also want a "quit" command, and I want it so that when I press = it will stop the program. However, not only does the code not work, but it also types "=" after it types/enters "potato". Can someone help? Thanks.
from pynput.keyboard import Key, Controller
import time
keyboard = Controller()
time.sleep(3)
while True:
keyboard.type('potato')
keyboard.press(Key.enter)
keyboard.release(Key.enter)
if keyboard.type('asdf'):
quit()
time.sleep(5)
P.S. no errors or anything

The most obvious answer here would be to change the "asdf" to "=" in the if statement, but if that doesn't fix the problem, you could add a listener to detect keypresses.
from pynput import keyboard, Key, Controller
import time
# set your termination key here
cut_key = "="
# check if key pressed is cut_key, if so, quit
def on_press(key):
try:
if key.char == cut_key:
quit()
except AttributeError:
if key == cut_key:
quit()
# non-blocking listener
listener = keyboard.Listener(
on_press=on_press)
listener.start()
keyboard = Controller()
time.sleep(3)
while True:
keyboard.type('potato')
keyboard.press(Key.enter)
keyboard.release(Key.enter)
time.sleep(5)
I didn't test this code, please comment if it doesn't work.
https://pynput.readthedocs.io/en/latest/keyboard.html

Related

exit loop pynput thread

Hello i'm trying to make a program to play snake using pynput.
When I press space the program runs but even if I press backspace i can't stop it, I know that I have to use threading but I don't figure how it works, thank you
my code :
from pynput import keyboard
from pynput.keyboard import Key, Controller
import threading
import time
kb = Controller()
def droite(key):
kb.press(Key.right)
kb.release(Key.right)
def gauche(key):
kb.press(Key.left)
kb.release(Key.left)
def haut(key):
kb.press(Key.up)
kb.release(Key.up)
def bas(key):
kb.press(Key.down)
kb.release(Key.down)
def on_press(key):
if key == Key.space:
print('yes')
droite(Key.right)
time.sleep(1.7)
haut(Key.up)
time.sleep(0.9)
gauche(Key.left)
time.sleep(2.15)
bas(Key.down)
time.sleep(1.9)
droite(Key.right)
time.sleep(2.15)
for i in range(255):
for i in range(6):
haut(Key.up)
time.sleep(0.1 )
gauche(Key.left)
time.sleep(2.1)
haut(Key.up)
time.sleep(0.1)
droite(Key.right)
time.sleep(2.1)
gauche(Key.left)
time.sleep(2.15)
bas(Key.down)
time.sleep(1.9)
droite(Key.right)
def on_release(key):
if key == Key.backspace:
print('no')
KeyboardInterrupt
return False
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
th1 = threading.Thread(target=on_press)
th1.start()
th2 = threading.Thread(target=on_release)
th2.start()
th1.join()
th2.join()
I'm trying to stop the program even if I'm in a loop when I press a key

Can a for loop be timed?

from ast import Break
import pyautogui as pat
import pyautogui
import time
import keyboard
# time.sleep(3)
# print(pat.position())
pat.click(x=712, y=1052, duration=1)
pat.click(x=1108, y=917)
file = open('peanut.txt', 'r').readlines()
for i in file:
pat.typewrite(i, interval=0.1)
pat.press('enter')
How do I time the for loop to stop or command the loop to stop by pressing a key?
I tried using the keyboard module but I could only find a simulation of the 'esc' key but I cannot seem to figure out what module would allow me to physically press a key to quit the program?? Any help would be fantastic. Thank you!
you can bind any key to stop loop
import keyboard
number=1
while True:
number=number+1
print(number)
keyboard.wait("escape")
try this code
this code will print a number and will wait escape, if escape is pressed will print another number infinitely
or you can do this
import keyboard
number=1
while True:
number=number+1
print(number)
if keyboard.is_pressed("escape"):
break
else:
pass
def AfterLoopWhile():
"""This code can't execute if the loop isn't break (Sorry for my
english)"""
print("Stopped the loop")
AfterLoopWhile() "If the loop is break, execute the function AfterLoopWhile
to stop the loop
or you can quit if escape is pressed
import keyboard
number=1
while True:
number=number+1
print(number)
if keyboard.is_pressed("escape"):
exit()
else:
pass

Multi - threading click macro / click recorder

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)

How to Detect 'ESC' keypress while expecting input() from user

I tried using
if msvcrt.kbhit():
key_stroke = msvcrt.getch()
if key_stroke==chr(27).encode(): #b'\x1b'
print ("Esc key pressed")
sys.exit()`
before and after the data=input('Enter a value:') but the Esc key_stroke not getting detected
That is, while expecting an input from user with input() function, if the user press Esc key, I want to do sys.exit()
Try this:
import sys
import msvcrt
def func():
print ('Enter user input:')
while True:
if msvcrt.kbhit():
key_stroke = msvcrt.getche()
if key_stroke==chr(27).encode():
print ("Esc key pressed")
sys.exit()
else:
#print (str(key_stroke).split("'")[1],"key pressed")
i=str(key_stroke).split("'")[1]+input()
print ("User input:",i)
func()
Note: I am using getche instead of getch, it is similar to getch but prints the key that is pressed.
This worked,
import msvcrt
data=input('Enter a value : ')
if(data):
print(data)
else:
print('invalid value')
key=msvcrt.getch()
if(msvcrt.getch() == chr(27).encode()):
print('Escape key pressed')
The main difference/relation between this and the said similar question is that,
The msvcrt.kbhit() couldn't be used with input() function. because it always doesn't wait for the keyboard hit. So directly using the msvcrt.getch() works perfectly.
Both the code provided for the question is mainly based on msvcrt library and that library didn't work as expected in the Python IDLE console, but perfectly in the windows command prompt
Please correct me if I am wrong

How to break a while true with keyboard interruption?

How can I break a while True if I press a key?, and if it is possible, how can I break a while True if a press an x key (e.g. intro)?.
while True:
if something is pressed:
print("STOP")
break
do_something()
I tryied with inputs but you can't put:
while True:
i = input() or None if program wait > 3 seconds. # > = more than
if != None:
print("STOP")
break
do_something()
Input stop all the while waiting for answer, and i don't want that.
PD: I use win 10 64-bits, python 32-bits 3.6, terminal.
PD2: Before post this question I search more about it, i found:
while True:
try:
do_something()
except KeyboardInterrupt:
pass
But this only stop with Ctrl + c, not other keys.
This only works in Windows:
import msvcrt
while True:
if msvcrt.kbhit():
break
The msvcrt provide a list of functions capables of process key inputs. msvcrt.kbhit() check if a key was pressed and it's waiting for been read and return true or false based on that.

Resources