It just doesnt work i get an error saying
AttributeError: 'Controller' object has no attribute 'is_pressed'
Code:
from pynput.mouse import Button, Controller
from pynput.keyboard import Key, Controller
from pynput.keyboard import Controller
from pynput import mouse
from pynput import keyboard
keyboard = Controller()
while True:
if keyboard.is_pressed('u'):
keyboard.press('w')
keyboard.release('w')
Can someone help me out!
pynput has special class Listener to catch pressed keys. It runs in thread and it doesn' need while True so it doesn't block main code.
Press ESC to stop it.
from pynput.keyboard import Key, Controller, Listener
def on_press(key):
print('{} pressed'.format(key))
#print(dir(key))
try:
if key.char == 'u':
keyboard.press('w')
keyboard.release('w')
except Exception as ex:
print(ex)
def on_release(key):
print('{} release'.format(key))
if key == Key.esc:
# Stop listener
return False
# --- main ---
keyboard = Controller()
listener = Listener(on_press=on_press, on_release=on_release)
listener.start()
# ... other code ...
listener.join()
BTW:
If you want global macros/hotkeys in system and use Linux then you could use special program AutoKey for this. It is created with Python and it is has GUI to create macros/script/etc.
If you want global macros/hotkeys in system and use Windows you could rather use popular AutoHotKey
If you want to create macros/hotkeys in some GUI programs then you should use GUI functions for this.
View the documentation, here's a snippet from it below.
Global hotkeys
A common use case for keyboard monitors is reacting to global hotkeys.
Since a listener does not maintain any state, hotkeys involving
multiple keys must store this state somewhere.
pynput provides the class pynput.keyboard.HotKey for this purpose. It contains two methods to update the state, designed to be easily
interoperable with a keyboard listener: pynput.keyboard.HotKey.press
and pynput.keyboard.HotKey.release which can be directly passed as
listener callbacks.
[...]
This will create a hotkey, and then use a listener to update its
state. Once all the specified keys are pressed simultaneously,
on_activate will be invoked.
Note that keys are passed through pynput.keyboard.Listener.canonical
before being passed to the HotKey instance. This is to remove any
modifier state from the key events, and to normalise modifiers with
more than one physical button.
The method pynput.keyboard.HotKey.parse is a convenience function to
transform shortcut strings to key collections. Please see its
documentation for more information.
To register a number of global hotkeys, use the convenience class
pynput.keyboard.GlobalHotKeys:
Related
I'm using the python pynput module to send emulated keypresses to my computer. I've tried it also with pyautogui, but either case has a problem: I'm trying to detect my own keypresses simulatneously, and my program is detecting the pynput emulated keypresses as well, with no way of filtering them.
from pynput.keyboard import Key, Listener, Controller
keyboard = Controller()
def write(word):
global keyboard,typing
keyboard.type(word)
def on_press(key):
global curword
key = str(key).replace("'","")
if key.isalpha():
write("hello") #when it detects a letter being pressed, it writes hello
def on_release(key):
pass
with Listener(on_press=on_press,on_release=on_release) as listener:
listener.join() #detects keypresses
Essentially, I'm trying to make a code that just autocompletes words when I type them, but when the program 'writes' the word out, the pynput listener detects the controller typing and creates an infinite loop.
I have a Python module that listens for a key combination using pynput then, once it's pressed, it types a string into a text program.
It works great! Except...
In the example below, the user's key combo is set to shift + space. This makes a lot of sense and will likely be the most common chosen key command for Windows users running my program. The trouble is, while the shift key is held down it changes what pynput types. Instead of 01/20/2019, it will type )!/20/2019.
I need a way to disable the keyboard until pyautogui is finished typing the string. Thanks a lot for your help!!!
Bonus question: I can't seem to get a result when the key combination includes a ctrl key. Key.ctrl simply fails to ever trigger, whilst other keys work fine.
from pynput.keyboard import Key, Controller, Listener
import time
keyboard = Controller()
def insert(): # check line 1 of config file
keyboard.type('01/20/2019')
# The currently active modifiers
current = set()
def on_press(key):
if key in COMBINATION:
current.add(key)
if all(k in current for k in COMBINATION): # I don't know what this k in current for k shit is.
current.remove(key)
insert() # run insert
if key == Key.esc:
listener.stop()
def on_release(key):
try:
current.remove(key)
except KeyError:
pass
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
``
You can use pyautogui.keyUp("shift") before you type.
def insert():
f=open('tc.txt')
line=f.readlines()
insert.timestamp=(line[0])
time.sleep(.1)
pyautogui.keyUp("shift")
pyautogui.typewrite(insert.timestamp)
"You've pressed the Enter Key!"
Whenever I press Key(z) the function should be executed:
#Pseudocode:
bind(<Enter>, function_x)
I'm currently working on a python program, which will run in a constant loop. It runs only on the console (no GUI), but still I need to be able to interact with the program at any time without having the program asking for input.
Several Modules solve this Problem
Pynput
(pip install pynput)
Simple module for handling and controlling general inputs
from pynput import keyboard
from pynput.keyboard import Key
def on_press(key):
#handle pressed keys
pass
def on_release(key):
#handle released keys
if(key==Key.enter):
function_x()
with keyboard.Listener(on_press=on_press,on_release=on_release) as listener:
listener.join()
(See pynput docs)
Keyboard (pip install keyboard)
A simple module for simulating and handling keyboard input
keyboard.add_hotkey('enter', lambda: function_x())
(See Keyboard docs)
Tkinter
Integrated UI Module, can track inputs on focused thread
from tkinter import Tk
root = Tk() #also works on other TK widgets
root.bind("<Enter>", function_x)
root.mainloop()
Be aware: These solutions all use Threading in some way. You might not be able to execute other code after you've started listening for keys.
Helpful threads:
KeyListeners, Binding in Tkinter
feel free to add more solutions
No beans with module keyboard.
Simply way to clear screen:
print('\033[2J') # clear screen, but stay current cursor line
print('\033[H') # move cursor 1,1 home position
or
print('\033[H\033[2J') # one step to clear screen and move at home position
You may define function like:
def cls():
print('\033[H\033[2J')
It works with tedious call braces.
I like to bind previous functionality to keyboard 'scroll lock' key, but how?
I'm making a python program that changes my wallpaper every hour, but i want to be able to also change the wallpaper when i press a certain button.
this is the code i've tried
while True:
key = ord(getch())
but the only bad part is that it gets stuck on that until i press something. Is there a better way to do this?
You may be able to achieve what you want by using https://pypi.python.org/pypi/pynput.
See also its docs on pythonhosted http://pythonhosted.org/pynput/, especially the section about monitoring the keyboard http://pythonhosted.org/pynput/keyboard.html#monitoring-the-keyboard.
The following is an example from the docs:
from pynput.keyboard import Key
from pynput.keyboard import Listener
def on_press(key):
print('{0} pressed'.format(
key))
def on_release(key):
print('{0} release'.format(
key))
if key == Key.esc:
# Stop listener
return False
# Collect events until released
with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
It will print every key you press until you press ESC, after which it will terminate.
Note that there are some operating system specific things to consider, for example on OSX the process must run as root.
I somehow accidentally found this.
import msvcrt
if msvcrt.kbhit():
Key = ord(getch())
if Key ==96:
#Do something here
And that seems to work. I think msvcrt.kbhit() is waiting for an keypress. Key = ord(getch()) takes the keypress and if Key ==96: checks if its the right keypress
I programmed a standard keylistener with pynput, but when using keyboard.type, it seems like the keys are released twice.
from pynput.keyboard import Controller, Listener
keyboard = Controller()
def on_release(key):
print('key {} released'.format(key))
if key.char == 'a':
keyboard.type('b')
with Listener(on_release=on_release) as listener:
listener.join()
# Pressing 'a' yields:
#
# key u'a' released
# key u'b' released
# key u'b' released
It doesn't seem like the key is pressed twice, only released twice. Is this the intended behavior? If not, what should be done to avoid this?
This is a bug in pynput.
As you have noticed, events can reach a Listener both from the system and when Controllers are invoked. The latter is true only for Xorg and win32, as they do no propagate synthetic events to listeners.
Or so I thought. It turns out that on win32, this is true only for mouse events; keyboard events appear to propagate normally. In any case, I have pushed a proposed solution here.
If you have the opportunity to test it, I would be grateful, otherwise I will merge it into master in a couple of days and make a new release. I only have access to win32 through VirtualBox, so I would appreciate some more bare-metal testing.