1

I just found out about the pynput library which is exactly what I have been looking for. My goal is to capure the keys the user is typing and whenever a specific sequence of keys was captured I want the computer to write a sequence to the current carret's position. After that I want to capture the users´s keys again until another noteworthy sequence occurs. And so on.

The problem is that the simulated key strokes of keyboard.write() are also considered by the Listener which leads to an infinite loop which was funny the first time it occurred but I am trying to get rid of it now obv.

My approach is to stop the Listener and create a new one after the computer is done typing but this process slows down a lot after the first start_listener() invocation and isn't optimal in the first place I think. And I am out of further ideas so I was hoping someone could help here.

Here is my code so far:

import keyboard
from pynput.keyboard import Key, Listener

def on_press(key):
   stop_listener()
   keyboard.write("Hello", 0.05)
   start_listener()

def on_release(key):
    if key == Key.esc:
        return False

def start_listener():
    global listener
    listener = Listener(on_press=on_press, on_release=on_release)
    listener.start()
    listener.join()

def stop_listener():
    global listener
    listener.stop()

with Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

martineau
  • 119,623
  • 25
  • 170
  • 301
  • I think these two modules are incompatible which makes it hard if not impossible to use them together. Can't you use `pynput` to send the simulated key strokes? – martineau Jun 07 '21 at 23:27
  • you can use `pynput.keyboard.Control` to send keys – furas Jun 07 '21 at 23:48
  • isntead of stoping and starting you could use some variable to control it - ie. `paused = True`, `keyboard.write(...)` and `paused = False`. And in other part `if not paused: ....` – furas Jun 07 '21 at 23:51

2 Answers2

1

There is a simple solution to the problem. I actually missed that I used two packages that have nothing to do with each other. Thanks to the ease to install them on my IDE.

Anyway my solution is now to only use the already present keyboard package https://pypi.org/project/keyboard/ and not pynput.keyboard

It turn out to be really easy when not using two separate packages :).

Here is the code:

# coding=utf8

import keyboard as k

def on_press(key = k.KeyboardEvent):
    
    k.write(key.name, 0.0)

k.on_press(on_press)
k.wait()
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
0

On my Linux Mint I need admin privileges to run keyboard but I can do the same with pynput.keyboard.Controller and methods press(), release(), time.sleep()

Instead of stoping and starting listenere I would use global variable paused = False to control when on_press should runs code.

from pynput.keyboard import Key, Listener, Controller
import time

keyboard = Controller()

def on_press(key):
    global paused  # inform function to assign new value to global variable (instead of creating local variable)
    
    if not paused:
        paused = True
        #keyboard.type("Hello")         # module pynput.keyboard.Controller
        for char in "Hello": 
            keyboard.press(char)    # pynput.keyboard.Controller
            keyboard.release(char)  # pynput.keyboard.Controller
            time.sleep(0.05)
        paused = False

def on_release(key):
    if not paused:
        if key == Key.esc:
            return False

# global variable with default value at start
paused = False

with Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

Tested on Linux Mint 20, Python 3.8.5, pynput 1.7.3

furas
  • 134,197
  • 12
  • 106
  • 148
  • This is not working it is still an infinite loop. – NoCodeNoBlunder Jun 08 '21 at 08:17
  • this works for me on Linux Mint. If this doesn't work on your system then it will need dig deeper in source code to get solution only for your system. – furas Jun 08 '21 at 12:40
  • I have tried this approch myself before posting here really surprised it works for you. I have found a sollution without using pynput now. – NoCodeNoBlunder Jun 09 '21 at 18:56
  • did you run it on Linux? It may works different on different systems. If you found solution then put it as asnwer - it can be useful for other users. And you can mark your answer as accepted. And few minutes later you can upvote your answer. – furas Jun 09 '21 at 19:12
  • I did not run it on Linux only on Windows. Yeah I am gone put my sollution now – NoCodeNoBlunder Jun 10 '21 at 07:18
  • I thought its not well seen to answer your own problem on stack. Thats why I was a little hesitant. – NoCodeNoBlunder Jun 10 '21 at 07:33