I want to stop the function so I can run a different one, this is my code:
from pynput import keyboard
import os, sys
import pygame
import time
from pygame import mixer
from pynput import mouse
from pygame import mixer
pygame.mixer.init(buffer=10)
from pynput.keyboard import Key, Listener
def click0():
def on_press(key):
print("HARD CLICK")
def click1():
def on_press(key):
print("MEM CLICK")
def click2():
def on_press(key):
print("SOFT CLICK")
# Collect events until released
with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
while True:
click0()
time.sleep(1) #sleep for 1 second
click1()
time.sleep(2) #sleep for 1 second
click2()
I want it to be like this:
from pynput import keyboard
import os, sys
import pygame
import time
from pygame import mixer
from pynput import mouse
from pygame import mixer
pygame.mixer.init(buffer=10)
from pynput.keyboard import Key, Listener
def click0():
def on_press(key):
print("HARD CLICK")
def click1():
def on_press(key):
print("MEM CLICK")
def click2():
def on_press(key):
print("SOFT CLICK")
# Collect events until released
with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
while True:
click0()
time.sleep(1) #sleep for 1 second
click0(quit)
click1()
time.sleep(2) #sleep for 1 second
click1(quit)
click2()
So I want to code the have 3 funcstions and it loops taking turns like: click1 (IS LOOPING), click2 (IS LOOPING), click3 (IS LOOPING), click1 (IS LOOPING), click..
But I want to stop the funcstion before running a diffent one like: click1 (IS LOOPING), click1 (STOPPED) click2 (IS LOOPING), click2 (STOPPED) click3 (IS LOOPING), click3 (STOPPED) click..
Any help please?
Consider using the async & return operators:
async def click0():
#.. do things
return
async def click1():
#.. do things again
return
async def main():
while True:
await click0()
await click1()
This await method essentially waits till a function is finish before moving onto the next line, so here the click0 function will need to complete before click1() executes,
alternatively, you can call click1 from click0, and click2 from click1 and so on...
Related
I am trying to make a python autoclicker as seen below:
import queue
from pynput import mouse
from pynput.mouse import Controller, Button
from sys import exit
from threading import Thread
from time import sleep
from keyboard import is_pressed
mouse = Controller()
failSafeKey = 'q'
delay = 1
def clicking():
while TRUE:
mouse.click(Button.left)
sleep(delay)
def failSafe():
while TRUE:
if is_pressed(failSafeKey):
exit()
print("exiting")
sleep(0.1)
delay = float(input("Enter delay: "))
failSafeKey = input("Enter failsafe key (ex. ctrl+s or q): ")
Thread(clicking())
Thread(failSafe())
However, whenever I press the failsafe key, nothing happens. I have tried removing the threads, but nothing changed. Can anyone give pointers on what might be happening?
The purpose of my code is to continuously type a letter very fast. It starts when a certain key is pressed (in this case f3) and stops when another key is pressed (f4). My code looks like this currently.
from pynput.keyboard import Controller, Listener
import time
keyboard = Controller()
confirm = False
def on_press(key):
if "f3" in str(key):
global confirm
confirm = True
while confirm:
keyboard.press('e')
keyboard.release('e')
time.sleep(0.10)
elif "Key." in str(key):
pass
def exit_loop(key):
if "f4" in str(key):
global confirm
confirm = False
elif "Key." in str(key):
pass
with Listener(on_press=on_press) as ListenerStart:
ListenerStart.join()
with Listener(on_press=exit_loop) as ListenerEnd:
ListenerEnd.join()
My problem is that, while starting the program with the f3 key works, I am unable to stop the program with f4. Also, the program is supposed to be paused, not exited from. Any help would be appreciated. Thanks.
If you have long-running code like while-loop then you have to run it in separated thread - because it blocks current code and it can't check if you press f4.
If you want to pause code then you should use some variable - ie. paused = True - to control if code inside while-loop should be executed or skiped.
And then you need only one Listener to check keys and check if paused is True or False
from pynput.keyboard import Controller, Listener
import time
import threading
def function():
keyboard = Controller()
while True:
if not paused:
keyboard.press('e')
keyboard.release('e')
time.sleep(0.1)
def on_press(key):
global paused
if paused:
if "f3" in str(key):
paused = False
else:
if "f4" in str(key):
paused = True
# global variables with default values at star
paused = True
# run long-running `function` in separated thread
thread = threading.Thread(target=function) # function's name without `()`
thread.start()
with Listener(on_press=on_press) as listener:
listener.join()
In corrent code you could use the same f3 to start and pause loop.
from pynput.keyboard import Controller, Listener
import time
import threading
def function():
keyboard = Controller()
while True:
if not paused:
keyboard.press('e')
keyboard.release('e')
time.sleep(0.1)
def on_press(key):
global paused
if "f3" in str(key):
paused = not paused
# global variables with default values at star
paused = True
# run long-running `function` in separated thread
thread = threading.Thread(target=function)
thread.start()
with Listener(on_press=on_press) as listener:
listener.join()
This code could be more complex - f3 could check if thread already exists and create thread when it doesn't exist.
from pynput.keyboard import Controller, Listener
import time
import threading
def function():
keyboard = Controller()
while True:
if not paused:
keyboard.press('e')
keyboard.release('e')
time.sleep(0.1)
def on_press(key):
global paused
global thread
if "f3" in str(key):
paused = not paused
if thread is None:
# run long-running `function` in separated thread
thread = threading.Thread(target=function)
thread.start()
# global variables with default values at star
paused = True
thread = None
with Listener(on_press=on_press) as listener:
listener.join()
import keyboard
while True:
if keyboard.is_pressed('b'):
print('a')
break
This is my code it prints a when I press b.
but I want it to keep printing a when I'm holding b how do I do this.
I use this module pynput mostly for mouse events, but it handles keyboard events too.
Here is the link: https://pypi.org/project/pynput/
This library allows you to control and monitor input devices.
Currently, mouse and keyboard input and monitoring are supported.
Instruction for keyboard midway down the page:
from pynput.keyboard import Key, Controller
keyboard = Controller()
or more appropriately use pynput.keyboard.Listener like this:
from pynput import keyboard
The code below detects multiple inputs. You would have to modify it for the a to b example given in the original question.
from pynput import keyboard
def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False
# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
# ...or, in a non-blocking fashion:
listener = keyboard.Listener(
on_press=on_press,
on_release=on_release)
listener.start()
Thank you.
How about adding a small delay after the print function to allow the program to re-evaluate if the input is still being pressed?
import keyboard
import time
while True:
if keyboard.is_pressed('b'):
print('a')
time.sleep(0.1)
I have a function that is called on_press. However, if the user constantly hits the key the keyboard event buffer queue gets really large and my function (which takes a few hundreds of ms) gets called even after the user has stopped pressing the key. How can I solve this issue?
from pynput import keyboard
def f1():
print("starting f1()..")
# f1 takes time to finish
def on_press(key):
print("pressed some key")
f1()
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
You could create a thread or process to achieve that,If you want to use thread, like this below:
from pynput import keyboard
import threading, time
def task():
time.sleep(3) # Simulate the time of cost
print("task finish")
def f1():
print("starting task..")
# f1 takes time to finish
# create a thread to execute the task.
threading.Thread(target=task).start()
def on_press(key):
print("pressed some key")
f1()
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
For sure, you could reduce the amount of functions,just for easy to understand, so I define 3 functions.
An answer is given here: https://pythonadventures.wordpress.com/2019/11/16/flush-the-stdin/
The solution is to flush the buffer with:
import sys
import termios
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
You can create a queue to store the incoming keyboard keys and only add to it when it is empty like so:
from pynput import keyboard
from queue import Queue
queue = Queue()
def on_press(key):
if queue.empty():
queue.put(key)
listener = keyboard.Listener(on_press=on_press)
listener.start()
while True:
key = queue.get()
f1()
I have a Function which keep listening.. I want to stop the Listener after a particular time
import time
from pynput.keyboard import Listener
with Listner(on_press=onPress) as l:
l.join
this is an Endless Loop... i want to Stop the listener after a particular time
You could use timer:
from threading import Timer
from pynput.keyboard import Listener
def on_press(key):
print(key)
with Listener(on_press=on_press) as l:
Timer(5, l.stop).start()
l.join()
print('5 seconds passed')
import time
from pynput.keyboard import Listener
from threading import Thread
def on_press(key):
print(f"Key pressed: {key}")
with Listener(on_press=on_press) as ls:
def time_out(period_sec: int):
time.sleep(period_sec) # Listen to keyboard for period_sec seconds
ls.stop()
Thread(target=time_out, args=(5.0,)).start()
ls.join()