2019/01/07

Python 的 kbhit() 和 getch()

開發靠鍵盤控制的程式時,通常會需要以下兩個功能:
  • kbhit() 偵測是否有按鍵
  • getch() 讀取按鍵
因為要跨平台,所以決定用 Python 來開發,這時才發現上述兩個功能並沒有很標準的解法。再加上除了一般按鍵,還要支援功能鍵、方向鍵等特殊按鍵,讓這件事更加麻煩。折騰很久才找到既簡單又漂亮的解法,getkey。

getkey 直接用 pip 安裝即可:
pip install getkey
使用範例如下:
#!/usr/bin/env python3

from getkey import getkey, keys

while True:
    k = getkey(blocking=False)
    if len(k) > 0:
        if len(k) == 1:
            if keys.name(k) == "ESC":
                break
            print(k)
        else:
            print(keys.name(k))
簡單說明如下:
  • blocking=False 代表不管有沒有按鍵 getkey() 都會馬上返回,從返回值就可以判斷是否有按鍵
  • 若是一般按鍵,如 '0'~'9'、'A'~'Z' 等,返回值長度是 1,可以直接拿來用
  • 若是功能鍵、方向鍵等,返回值長度大於 1,建議用 keys.name() 來翻譯
這個解法的好處在於將平台的差異完全隱藏,可以支援 Windows、Unix/Linux、MacOS,甚至 Cygwin 等等,也可以正確解出功能鍵和方向鍵等。

有缺點嗎?有。原作者似乎不再更新和修正,在 Windows 上的 Python 3.x 安裝和使用會有一些問題,請參考原作者原專案的待解問題清單:
https://github.com/kcsaff/getkey/issues
所幸,有善心人士提供 修正版,但須下載原始碼來安裝:
git clone https://github.com/li-rupert/getkey.git
不會 git 的人,可以下載以下檔案解開:
https://github.com/li-rupert/getkey/archive/master.zip
安裝指令如下:
python setup.py install

1 則留言:

貓爸文雜 提到...

感恩,原來在raspberry上能用evdev來接收無人登入的key input(自動MP3播放器),後來移殖WSL發生找不到/dev/input的狀況,應該是我沒考慮WSL一定是在有人登入才能使用的狀況,用了你的方法,順利解決