Python按键按下和释放监听器

7
我正在使用Python代码控制远程玩具车。目前,代码如下所示:

def getkey():
        fd = sys.stdin.fileno()
        old = termios.tcgetattr(fd)
        new = termios.tcgetattr(fd)
        new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO
        new[6][TERMIOS.VMIN] = 1
        new[6][TERMIOS.VTIME] = 0
        termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
        c = None
        try:
                c = os.read(fd, 1)
        finally:
                termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
        return c

def car():
    while True:
        key = getkey()
        if key == 's': #Down arrow
            print "Down"
            Backward()
        elif key == 'w': #Up arrow
            print "Up"
            forward()
        elif key == 'a': 
            print "left"
            Left()
        elif key == 'd': 
            print "Right"
            Right()
        elif key == 'q': #Quit
            print "That's It"
            break
def forward():
    GPIO.output(11,True)  #Move forward

当我按下 'w' 键时,将调用 forward() 方法并使汽车向前移动,但汽车不会停下,直到我退出程序或从其他方法中调用 GPIO.output(11, False)
是否有任何键侦听器可以检测特定键的释放?
例如,如果按下 'w' 键调用此方法,松开时调用另一个方法。
伪代码:
if w_isPressed()
   forward()
else if w_isReleased()
    stop()

1
你没有实际的键盘访问权限,因此你无法进行此操作。你的终端只能发送按键,所以你无法确定何时释放了某个按键。 - Blender
1
你可以尝试使用PyGame来完成它。 - kindall
2个回答

3
我曾经看到过Pygame游戏开发库在类似的场景中被成功地使用,处理实时系统和机器生产,而不仅仅是玩具示例。我认为它在这里也是一个合适的候选者。查看pygame.key模块以了解可以通过键盘输入做什么。
简而言之,如果您不熟悉游戏开发,您基本上会在“无限”游戏循环内持续轮询事件,如输入状态更改,并相应地做出反应。通常使用每个已经流逝的时间差来更新系统的参数。有许多关于此方面的教程和Pygame可用,并且Pygame文档非常完整。
以下是一个简单的示例:
import pygame

pygame.init()

# to spam the pygame.KEYDOWN event every 100ms while key being pressed
pygame.key.set_repeat(100, 100)

while 1:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_w:
                print 'go forward'
            if event.key == pygame.K_s:
                print 'go backward'
        if event.type == pygame.KEYUP:
            print 'stop'

您需要使用pygame.KEYDOWNpygame.KEYUPpygame.key.set_repeat来根据您的汽车运动是如何实现的进行调整。

3
Pygame的一个限制是需要连接显示器。也就是说,如果您使用SSH连接到没有显示器的树莓派,则此方法无法工作。 - malte

2

我曾遇到类似的问题(我不是Python专家),但这对我有用。

import pynput
from pynput import keyboard 

def on_press(key):
    try:
        print('Key {0} pressed'.format(key.char))
        #Add your code to drive motor
    except AttributeError:
        print('Key {0} pressed'.format(key))
        #Add Code
def on_release(key):
    print('{0} released'.format(key))
    #Add your code to stop motor
    if key == keyboard.Key.esc:
        # Stop listener
        # Stop the Robot Code
        return False

# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()

看起来pynput在没有焦点的情况下也能监听。在某些情况下可能是可取的。 - pianoJames

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接