I am trying to detect the keyboard presses just when I am in the cmd window running a ROS2 node.
I have already written this using pynput, but it detects all keys pressed even if I am in another window.
import sys
import os
import signal
import time
from pynput import keyboard
import rclpy
from rclpy.parameter import Parameter
import std_msgs.msg
class KeystrokeListen:
def __init__(self, name=None):
self.node = rclpy.create_node(name or type(self).__name__)
self.pub_glyph = self.node.create_publisher(std_msgs.msg.String, 'glyphkey_pressed', 10)
self.pub_code = self.node.create_publisher(std_msgs.msg.UInt32, 'key_pressed', 10)
def spin(self):
with keyboard.Listener(on_press=self.on_press, on_release=self.on_release) as listener:
while rclpy.ok() and listener.running:
rclpy.spin_once(self.node, timeout_sec=0.1)
@property
def logger(self):
return self.node.get_logger()
def on_release(self, key):
pass
def on_press(self, key):
try:
char = getattr(key, 'char', None)
if isinstance(char, str):
self.logger.info('pressed ' + char)
self.pub_glyph.publish(self.pub_glyph.msg_type(data=char))
else:
try:
# known keys like spacebar, ctrl
name = key.name
vk = key.value.vk
except AttributeError:
# unknown keys like headphones skip song button
name = 'UNKNOWN'
vk = key.vk
self.logger.info('pressed {} ({})'.format(name, vk))
# todo: These values are not cross-platform. When ROS2 supports Enums, use them instead
self.pub_code.publish(self.pub_code.msg_type(data=vk))
except Exception as e:
self.logger.error(str(e))
raise
if key == keyboard.Key.esc:
self.logger.info('stopping listener')
raise keyboard.Listener.StopException
os.kill(os.getpid(), signal.SIGINT)
def main(args=None):
rclpy.init(args=args)
KeystrokeListen().spin()
if __name__ == '__main__':
main()
I have found here How to detect key presses? something related with win32gui, as getting the name of the current window and then the name of the window we want the key presses to be detected:
from win32gui import GetWindowText, GetForegroundWindow
current_window = (GetWindowText(GetForegroundWindow()))
desired_window_name = "Stopwatch"
However, I just want for my program to work whenever I am in the cmd where I launched it.
Any idea??
Thank you in advance!