3

I am looking for a way to make my app get the input from keyboard when it's not being focused (I'm using Kivy).

And I'm currently using Pynput module to do the key detecting part, but it's doesnt seem to work very well.

-All of these problems only happen when you do not focus on your app. If your app is focused the Pynput Listener work very well.

For example: (This happens very randomly) you want to hold a key for 3 seconds then release, but the app refused to release instead it still detects that the key is still being held for 0.5 or 1 second more and then releases. (This is not my Kivy app problem, since the bug will not appear when using Kivy _on_key_down/release)

So basically you tell the system to hold a key (using Pynput Listener) for an amount of time, there will always chance the system will hold it longer than the time you gave which is very annoying and feel like a kind of lag.

So is there any other module that can detect the keyboard when the app is not being focused? Or at least can someone give me the idea to deal with this? (I'm using Window 10)

Ten Kho
  • 184
  • 10

2 Answers2

1

Try using the keyboard module. But there is one downside, you must run the file as root. But here is how you would do it:

import keyboard
import threading
# Do stuff
def key_handler():
    while app_is_running:
        key = keyboard.read_key()
        if key == "W":
            # do stuff
thread = threading.Thread(target=key_handler, daemon=True)
thread.start()
# Do stuff

This is not the only way you can do it, you can also use hotkeys

SimplyDev
  • 90
  • 2
  • 11
  • This is worth trying, but sadly I can't interfere with my App since it's running in a completely different thread. – Ten Kho Aug 18 '22 at 02:49
  • 1
    Well there is also a solution involving hotkeys. I don’t know much about it, but look [here](https://github.com/boppreh/keyboard#api) – SimplyDev Aug 18 '22 at 23:49
1

The start method from pynput's keyboard listener joins the listener with the current thread. So just call it in the thread that starts the Kivy application.

from kivy.app import App
from kivy.uix.label import Label
from pynput.keyboard import Listener


def on_press(key):
    print(f"Key press was listened to from Kivy event loop! Key pressed: {key}")


class TestApp(App):
    def build(self):
        return Label(text="Check console to witness keyboard being listened to")
    
    def run(self):
        Listener(on_press=on_press).start()
        super().run()


if __name__ == "__main__":
    TestApp().run()