Windows机器上Python的无缓冲字符输入

3 投票
3 回答
2664 浏览
提问于 2025-04-17 18:30

我想做的事情

我想设计一个带有圈速计时的秒表。当你按下"L"键时,表示完成一圈;当你按下"S"键时,所有圈速完成,时间会按顺序显示出来。

在C++中,我可以使用conio.h里的_getch()函数来实现,这样会比较简单。不过我想用Python来写这个程序,因为这样会更容易,而且在C++中处理时间也挺麻烦的。

我之前在这个链接上写过一个程序(是用来计时魔方的): 魔方计时器

问题

Python里没有像_getch()这样的函数。这就成了问题,因为在完成一圈后,你不能只按一个键再按回车,这样会浪费时间,还会让用户觉得烦。

我读过的东西

我了解过curses库,但可惜它没有Windows版本。

我尝试了一个据说能在网站上工作的程序。这个链接是: getch的链接

但它没有成功。

我尝试过的:

  1. msvcrt.getch()

    >>> import msvcrt
    >>> msvcrt.getch()
    '\xff'

我认为FF是255的十六进制表示。

我不明白为什么会这样。

  1. readch() ,这是@martineau建议的

    import msvcrt

    def readch(echo=True): "在Windows上获取一个字符。" while msvcrt.kbhit(): # 清空键盘缓冲区 msvcrt.getch() ch = msvcrt.getch() while ch in '\x00\xe0': # 是箭头键或功能键前缀吗? msvcrt.getch() ch = msvcrt.getch() # 第二次调用返回实际的键码 if echo: msvcrt.putch(ch) return ch.decode()

    a = []

    for i in range(10): a.append(readch())

我遇到的错误:

>>> 

Traceback (most recent call last):
  File "C:/Python25/1.py", line 30, in <module>
    a.append(readch())
  File "C:/Python25/1.py", line 25, in readch
    return ch.decode()
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)

我需要帮助的

一个像_getch()那样的函数,或者在Windows机器上能用的类似功能。

机器规格

Python IDLE 2.5.4或2.6或2.7

Windows XP SP3

3 个回答

0

你不能在IDLE里使用msvcrt这个库。试试在Windows命令行里运行你的代码。

0

如果你在问怎么在没有输入的情况下读取输入,那你可能是在寻找绑定的方式。这个需要一个Tkinter窗口,我想是这样的。

lapEnded = bind_all("<KeyPress-l>", endLap)
stopRunning = bind_all("<KeyPress-s", noMoreRunning)

接着,你需要定义两个函数,endLapnoMoreRunning,它们各自完成自己的功能。根据你使用的Tkinter和/或Python的版本,bind_all可能只是叫bind。希望这能解答你的疑问。

3

这是我在Windows控制台中使用的一个方法,似乎效果不错。它和ActiveState的做法有点相似,不过这个只适用于Windows系统。这个方法是基于这份 msdn 文档中的_getwch()

#### windows only ####
import msvcrt

def readch(echo=True):
    "Get a single character on Windows."
    while msvcrt.kbhit():  # clear out keyboard buffer
        msvcrt.getwch()
    ch = msvcrt.getwch()
    if ch in u'\x00\xe0':  # arrow or function key prefix?
        ch = msvcrt.getwch()  # second call returns the actual key code
    if echo:
        msvcrt.putwch(ch)
    return ch

def pause(prompt='Press any key to continue . . .'):
    if prompt:
        print prompt,
    readch(echo=False)

(更新了以支持Unicode字符)。

撰写回答