实时抓拍和按键的处理(例如按键事件)

注:我想这样做,无需使用任何外部包装,像pygame的,等实时抓拍和按键的处理(例如按键事件)

我试图捕捉单个按键为他们到达并针对特定角色执行操作,无论我是仅仅想“重新回显”角色,还是根本不显示它并执行其他操作。

我已经找到了一个跨平台(虽然关于OS X不知道)的getch()实现,因为我不想念想输入一整行()的作用:

# http://code.activestate.com/recipes/134892/ 

def getch():

try:

import termios

except ImportError:

# Non-POSIX. Return msvcrt's (Windows') getch.

import msvcrt

return msvcrt.getch

# POSIX system. Create and return a getch that manipulates the tty.

fd = sys.stdin.fileno()

old_settings = termios.tcgetattr(fd)

try:

tty.setraw(fd)

ch = sys.stdin.read(1)

finally:

termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

return ch

[尝试1 ] 我第一次尝试了一个简单的while-true循环来轮询getch,但是如果我输入得太快,字符就会丢失。减少睡眠时间会使情况变得更糟。调试语句只在输入键的按下时打印,并且在时间和位置上不一致。 (看起来可能有一些线路缓冲正在进行?)取出环路和睡眠可以让它工作一次,但完美。

#!/usr/bin/env python3 

import sys

import tty

import time

def main():

while True:

time.sleep(1)

sys.stdout.write(" DEBUG:Before ")

sys.stdout.write(getch())

sys.stdout.write(" DEBUG:After ")

if __name__ == "__main__":

main()

[尝试2] 我得到一个例子使用螺纹的方法(https://stackoverflow.com/a/14043979/2752206),但它“锁死”,将不接受任何输入(包括Ctrl-C,和等等)..

#!/usr/bin/env python3 

import sys

import tty

import time

import threading

key = 'Z'

def main():

threading.Thread(target=getchThread).start()

while True:

time.sleep(1)

sys.stdout.write(" DEBUG:Before ")

sys.stdout.write(key)

sys.stdout.write(" DEBUG:After ")

def getchThread():

global key

lock = threading.Lock()

while True:

with lock:

key = getch()

if __name__ == "__main__":

main()

有没有人有任何建议或指导?或者更重要的是,有人可以解释为什么这两次尝试不起作用?谢谢。

回答:

首先,我没有真正需要多线程的东西。例如,如果您想要执行一些任务,比如在屏幕上绘图或执行任何操作,并在执行此操作时捕获密钥,则需要这样做。

让我们考虑一个情况,你只想捕获按键,并且在每个按键执行某个动作之后:退出,如果x被按下,否则只是打印字符。所有你需要的这种情况很简单,而循环

def process(key): 

if key == 'x':

exit('exitting')

else:

print(key, end="", flush=True)

if __name__ == "__main__":

while True:

key = getch()

process(key)

通知没有睡眠()。我假设你认为getch()不会等待用户输入,所以你设置了1s的睡眠时间。但是,您的getch()等待一个条目,然后返回它。在这种情况下,全局变量并不是很有用,所以你可能只需在循环中调用process(getch())。

print(key, end="", flush=True) =>额外的参数将确保按下的键保持在一行,而不是每次打印某些内容时都追加换行符。

另一种情况,你想同时执行不同的东西,应该使用线程。

考虑以下代码:

n = 0 

quit = False

def process(key):

if key == 'x':

global quit

quit = True

exit('exitting')

elif key == 'n':

global n

print(n)

else:

print(key, end="", flush=True)

def key_capturing():

while True:

process(getch())

if __name__ == "__main__":

threading.Thread(target=key_capturing).start()

while not quit:

n += 1

time.sleep(0.1)

这将创建一个全局变量n并增加它在主线程第二10次。同时,key_capturing方法监听按键,并按照前面的示例+执行相同的操作,当您在键盘上按n时,将打印全局变量n的当前值。

结束语:正如@zondo指出的那样,您确实在getch()定义中错过了大括号。 return msvcrt.getch应该很可能是return msvcrt.getch()

以上是 实时抓拍和按键的处理(例如按键事件) 的全部内容, 来源链接: utcz.com/qa/265482.html

回到顶部