I want to make clicker for my game and i don't know how can I exit program after I press a key. I've tried
import sys
screenWidth, screenHeight = pyautogui.size()
currentMouseX, currentMouseY = pyautogui.position()
if keyboard.is_pressed("p"):
sys.exit()
for user in range(0, 1):
pyautogui.moveTo(849, 657) # załóż druzyne
pyautogui.click()
pyautogui.PAUSE = 0.2
pyautogui.typewrite('Bandaelo')
pyautogui.PAUSE = 0.3
pyautogui.moveTo(953, 742) # potwierdź
pyautogui.click()
pyautogui.PAUSE = 0.4
pyautogui.moveTo(948, 656) # potwierdz
pyautogui.click()
and more code like this
but it doesn't work. Can You help me?
This should do the trick, you still need to put your code:
import sys
import pyautogui
def main():
screenWidth, screenHeight = pyautogui.size()
currentMouseX, currentMouseY = pyautogui.position()
try:
while 1:
var = input("enter p to exit: ")
if var == 'p':
break
else:
print('test something')
# put your code here...
# and more code like this
except KeyboardInterrupt:
sys.exit()
raise
if __name__ == '__main__':
main()
You need to import sys object. Then call the exit() method to stop your program.
For your case you can try:
import keyboard
import sys
if keyboard.is_pressed("p"):
sys.exit()
EDIT : I have done a little research and find when writing a multithreaded app, raise SystemExit and sys.exit() both terminates only the running thread. In this case, you can use os._exit() which exits the whole process.
import os
import keyboard
if keyboard.is_pressed('p'):
os._exit(0)
Related
import time
import pyautogui
from pyautogui import *
import keyboard
from PIL import ImageGrab
import os
import win32api, win32con
import cv2
import pyperclip
from pynput.keyboard import Key, Listener
import pytesseract
##1340,182, 1777, 213
test = 0
def alertf1(c):
global test
while c == 1:
if keyboard.is_pressed('f1'): # if key 'f1' is pressed
print('f1 has been pressed')
c = 0
time.sleep(0.1)
test = test + 1
break
else:
print('checking if anything is destroyed')
time.sleep(1)
if pyautogui.locateOnScreen('destroy2.png', region=(1340,182, 1777, 230)):
print('something got destroyed!')
time.sleep(0.1)
pyautogui.keyDown('ctrl')
time.sleep(0.1)
pyautogui.keyDown('tab')
pyautogui.keyUp('ctrl')
pyautogui.keyUp('tab')
time.sleep(0.5)
for char in '#':
pyperclip.copy(char)
pyautogui.hotkey('ctrl', 'v', interval=0.1)
time.sleep(0.1)
pyautogui.write('everyone Enemies/Red Logs! Something has been destroyed.')
time.sleep(0.1)
pyautogui.press('enter')
time.sleep(5)
pyautogui.click(x=1860, y=50)
time.sleep(5)
else:
if keyboard.is_pressed('f1'): # if key 'f1' is pressed
print('f1 has been pressed')
c = 0
time.sleep(0.1)
test = test + 1
break
def on_press(key):
global test
if test > 0 and key == Key.f1:
c = 0
if key == Key.f1 and test == 0:
print('before alert f1 pressed')
time.sleep(0.1)
test = test + 1
alertf1(1)
if key == Key.f1 and test > 1:
test = 0
with Listener(on_press=on_press) as listener:
listener.join()
def main():
while True:
time.sleep(0.1)
print('on press going now')
on_press(key)
if __name__ == '__main__':
main()
my issue is that i want the turn on / off switch to use hte same key
and i can't think of a way to distinguish between when I press the key and when the program is simply on loop.
like F1 will start function alert, which will loop eternally, until I press F1, issue is that, if keyboard.is_pressed('f1'): isn't a great solution
because if code is somewhere else it wont recognize i pressed f1
I am building some macro program using pyautogui.
Unfortunately I am not able to stop for-loop so sometimes it takes too much time until for-loop end.
Is there any way to stop the program at any moment I want? or I just wait until program end.
below is my code
CURRENT_DIR = os.getcwd()
list = os.path.join(CURRENT_DIR,'BOM_list.xlsx')
df = pd.read_excel(list)
for i in df['MLFB'].index:
MLFB = df.loc[i, 'MLFB']
print(MLFB)
a = pyautogui.locateCenterOnScreen('a_material.png')
print(a)
pyautogui.moveTo(a)
pyautogui.moveRel(350, 0)
pyautogui.click()
pyautogui.keyDown('ctrl')
pyautogui.press('a')
pyautogui.keyUp('ctrl')
pyautogui.typewrite(MLFB)
b = pyautogui.locateCenterOnScreen('b_execute.png')
print(b)
pyautogui.moveTo(b)
pyautogui.click()
time.sleep(2.5)
pyautogui.keyDown('alt')
pyautogui.press('y')
pyautogui.press('t')
pyautogui.press('a')
pyautogui.press('i')
pyautogui.keyUp('alt')
time.sleep(2)
pyautogui.press('down')
pyautogui.typewrite(['enter'])
time.sleep(2)
c = pyautogui.locateCenterOnScreen('c_Directory.png')
pyautogui.moveTo(c)
pyautogui.moveRel(350, 0)
pyautogui.click()
pyautogui.keyDown('ctrl')
pyautogui.press('a')
pyautogui.keyUp('ctrl')
pyautogui.typewrite(CURRENT_DIR)
pyautogui.click()
time.sleep(1.5)
d = pyautogui.locateCenterOnScreen('d_Filename.png')
pyautogui.moveTo(d)
pyautogui.moveRel(350, 0)
pyautogui.click()
pyautogui.keyDown('ctrl')
pyautogui.press('left')
pyautogui.keyUp('ctrl')
pyautogui.typewrite(MLFB)
time.sleep(0.5)
pyautogui.typewrite(['enter'])
time.sleep(2)
e = pyautogui.locateCenterOnScreen('e_go_back.png')
pyautogui.moveTo(e)
pyautogui.click()
time.sleep(2)
PyAutoGUI has a built in failsafe to terminate the program at any time. Just move your mouse to the top left corner of your main monitor where your x, y values would be 0, 0.
Typing print(pyautogui.FAILSAFE) should return True, telling us the failsafe is on. You could also disable it if it's getting in the way of your program by setting it to pyautogui.FAILSAFE = False
Looking through your code, you could save some space by using hotkey() when you want to press more than one key at a time:
pyautogui.keyDown('ctrl')
pyautogui.press('a')
pyautogui.keyUp('ctrl')
Is the same as:
pyautogui.hotkey('ctrl', 'a')
You could also check out threading which allows you to run more than one process at a time.
The following code will have an example main program running and when the Esc key is pressed, the main program will pause and the user is prompted if they want to continue or not.
import time
from threading import Thread
from pynput import keyboard
def exit_program():
def on_press(key):
if str(key) == 'Key.esc':
main.status = 'pause'
user_input = input('Program paused, would you like to continue? (y/n) ')
while user_input != 'y' and user_input != 'n':
user_input = input('Incorrect input, try either "y" or "n" ')
if user_input == 'y':
main.status = 'run'
elif user_input == 'n':
main.status = 'exit'
exit()
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
def main():
main.status = 'run'
while True:
print('running')
time.sleep(1)
while main.status == 'pause':
time.sleep(1)
if main.status == 'exit':
print('Main program closing')
break
Thread(target=main).start()
Thread(target=exit_program).start()
Apologies for the newbie Python post, but a bit of Googling and I still can't find what I need.
I have the following Pi Hat; https://github.com/modmypi/Jam-HAT, ...and I'm using their docs to guide me; https://gpiozero.readthedocs.io/en/stable/recipes.html
My idea is pretty simple;
run script when button pressed
wait for it to run, showing flashy lights whilst running
if I press another button, stop/kill script
However, I'm stuck on the part where I need to stop the script with a button
#!/usr/bin/env python3
import gpiozero
import subprocess
from signal import pause
from time import sleep
button1 = gpiozero.Button(18)
button2 = gpiozero.Button(19)
green1 = gpiozero.LED(16)
green2 = gpiozero.LED(17)
red1 = gpiozero.LED(5)
red2 = gpiozero.LED(6)
script = ""
yellow1 = gpiozero.LED(12)
yellow2 = gpiozero.LED(13)
def kill_hello():
global script
script.kill()
print("Killed PID: ", script.pid)
red1.on()
sleep(.5)
red1.off()
red2.on()
sleep(.5)
red2.off()
def say_hello():
global script
green1.on()
sleep(.5)
green1.off()
green2.on()
sleep(.5)
green2.off()
script = subprocess.Popen(['/home/kali/hello.sh'])
print("Script PID: ", script.pid)
while script.poll() is None:
if not button2.when_pressed:
green1.on()
sleep(.5)
green1.off()
sleep(1)
button2.when_pressed = kill_hello
print("Press Ctrl & C to Quit")
try:
button1.when_pressed = say_hello
pause()
except KeyboardInterrupt:
print( "\n...Quit!")
I've tried a try/except where that while loop is, but that has also not worked (not like the KeyboardInterrupt). It doesn't recognise the button has been pressed, and I'm assuming because it's not within a valid catch/else/something block.
Any suggestions for a simple break out of loop, please?
It seems the issue is around a single process is hogging Python, thus creating multiple threads helped;
#!/usr/bin/env python3
import gpiozero
import subprocess
import time
import threading
from signal import pause
button1 = gpiozero.Button(18)
button2 = gpiozero.Button(19)
green1 = gpiozero.LED(16)
green2 = gpiozero.LED(17)
red1 = gpiozero.LED(5)
red2 = gpiozero.LED(6)
script = ""
yellow1 = gpiozero.LED(12)
yellow2 = gpiozero.LED(13)
switch = True
def blink():
def run():
while (switch == True):
green1.on()
time.sleep(.2)
green1.off()
time.sleep(.2)
if switch == False:
break
thread = threading.Thread(target=run)
thread.start()
def switchon():
global switch
global script
switch = True
print('switch on')
script = subprocess.Popen(['/home/kali/hello.sh'])
blink()
def switchoff():
global switch
global script
print('switch off')
script.kill()
switch = False
try:
button1.when_pressed = switchon
button2.when_pressed = switchoff
pause()
except KeyboardInterrupt:
print( "\n...Quit!")
I want to have a loop running that will print "Hello" and when I press "K" it stops printing but it doesn't end the program, then when I press "K" again it starts printing again.
I tried this(using the keyboard module):
import keyboard
running = True
while running == True:
print("hello")
if keyboard.is_pressed("k"):
if running == True:
running = False
else:
running = True
but when I press the button it just ends the program and that's not what I'm trying to do. I understand why it ends but I don't know how to make it not end. How can I do that?
import keyboard
running = True
display = True
block = False
while running:
if keyboard.is_pressed("k"):
if block == False:
display = not display
block = True
else:
block = False
if display:
print("hello")
else:
print("not")
Maybe something like that:
import keyboard
running = True
stop = False
while !stop:
if keyboard.is_pressed("k"):
running = !running # Stops "hello" while
if keyboard.is_pressed("q"):
stop = !stop # Stops general while
if running:
print("hello")
You could use a handler for the keypress, which sets an event that the main thread can then test for periodically, and wait if required.
(Note that there are two types of events here, the keypress event and the setting of the running, so these should not be confused.)
from threading import Event
from time import sleep
import keyboard
hotkey = 'k'
running = Event()
running.set() # at the start, it is running
def handle_key_event(event):
if event.event_type == 'down':
# toggle value of 'running'
if running.is_set():
running.clear()
else:
running.set()
# make it so that handle_key_event is called when k is pressed; this will
# be in a separate thread from the main execution
keyboard.hook_key(hotkey, handle_key_event)
while True:
if not running.is_set():
running.wait() # wait until running is set
sleep(0.1)
print('hello')
import sys
import keyboard
from time import sleep
running = True
while running:
if keyboard.is_pressed("k"):
sleep(1)
elif keyboard.is_presed('Esc'):
sys.exit()
else:
print("hello")
I didnt test it, so please give me feedback
I think the right way is flushing the buffer, because the previous solutions may print more. This works for windows, for Linux, you should refer to Python read a single character from the user
import time
import subprocess
import sys
import msvcrt
printing = True
while (1):
# Try to flush the buffer
while not msvcrt.kbhit() and printing:
print("hello")
doit = msvcrt.getch().decode('utf-8')
if doit=="k":
printing = not printing
print("stop/start")
if doit == 'q':
break
This is the output of this code:
Please note that, if you add print("stop/start") in Adrian Melon's program, you can see his program prints several time "hello" after 'k' is pressed until the buffer will be empty.
import keyboard
running = True
display = True
block = False
while running:
if keyboard.is_pressed("k"):
print("stop/start")
if block == False:
display = not display
block = True
else:
block = False
if display:
print("hello")
else:
pass
This is the output of #Adrian-Melon program:
import keyboard
running = True
display = True
block = False
while running:
if keyboard.is_pressed("space"):
if block == False:
display = not display
block = True
else:
block = False
if display:
print("hello")
else:
input("Press Enter to continue...")
if block == False:
display = not display
block = True
You can use this to stop and start again.
Im trying to move my Cursor every three seconds and if it went too far, reset it to its original location. I want the program to stop after I press any key on the keyboard.
It doesnt seem to work though... what could I be missing? This is what I came up with:
import win32api, win32con, time, sys, msvcrt
global z
z=10
def kbfunc():
#this is boolean for whether the keyboard has bene hit
x = msvcrt.kbhit()
if x:
sys.exit
else:
ret = False
return ret
def move(x,y):
win32api.mouse_event(win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, int(x/1920*65535.0), int(y/1080*65535.0))
while True:
move(960,540+z)
time.sleep(3)
if z>100:
move(960,540)
z += -100
z + 10
kbfunc()
First, you need to install the keyboard module:
pip3 install keyboard
And than add it to your loop:
import keyboard
while True:
move(960,540+z)
time.sleep(3)
if z>100:
move(960,540)
z += -100
z + 10
if keyboard.is_pressed('q'): # if key 'q' is pressed
print('You Pressed A Key!')
break # finishing the loop
I would guess that msvcrt.kbhit() does not store previous hits. It only tells you if a key is hit at the current moment in time. You can loop checking for keyboard hits. If no hits before 3 seconds, return:
import time
import msvcrt
import sys
def kbfunc(max_time=3):
start = time.time()
while not msvcrt.kbhit():
end = time.time()
if end - start >= max_time:
break
else:
sys.exit()
After trying around with the given answers, the finished solution looks like this:
global z
z=10
def move():
mouse.move(10, 10, absolute=False, duration=1)
def moveback():
mouse.move(-10, -10, absolute=False, duration=1)
while True:
move()
time.sleep(3)
moveback()
if keyboard.is_pressed('q'): # if key 'q' is pressed
break # finishing the loop