首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python Windows 主控台讀取功能鍵 (F1-F12、方向鍵) 完整方法

     編輯:更多程式設計知識

Windows 主控台下,功能鍵(F1-F12、方向鍵、Home/End 等)不像一般字元鍵有單一 ASCII 碼,而是發送「擴展鍵掃描碼」序列。本文詳細說明讀取原理與完整程式碼實作。

鍵盤輸入序列原理

  • 一般字元鍵:單一位元組,如 'a' = 0x61。
  • 功能鍵/方向鍵:兩個位元組序列:
    1. 首位元組:0x00 (NUL) 或 0xE0 (224) —— 標記為擴展鍵。
    2. 次位元組:掃描碼,如 0x48 (Up)、0x3B (F1)。
  • 組合鍵:Ctrl+字元 產生控制碼(如 Ctrl+A = 0x01),非擴展序列。

核心讀取函式


import msvcrt

def get_key():
    """讀取單一按鍵,回傳 (key_type, key_code)
    key_type: 'char' | 'function' | 'ctrl'
    key_code: 字元碼或掃描碼
    """
    if not msvcrt.kbhit():
        return None, None
    
    first = msvcrt.getch()
    first_ord = ord(first)
    
    # 擴展鍵標記:0x00 或 0xE0
    if first_ord in (0x00, 0xE0):
        second = msvcrt.getch()
        second_ord = ord(second)
        # 合成掃描碼:首位元組 * 256 + 次位元組
        scan_code = first_ord * 256 + second_ord
        return 'function', scan_code
    
    # Ctrl+字元 產生 1-26 控制碼
    if 1 <= first_ord <= 26:
        return 'ctrl', first_ord
    
    # 一般可列印字元
    return 'char', first_ord

# 常見功能鍵掃描碼對照表 (首位元組 0x00 或 0xE0)
KEY_MAP = {
    0x003B: 'F1',  0x003C: 'F2',  0x003D: 'F3',  0x003E: 'F4',
    0x003F: 'F5',  0x0040: 'F6',  0x0041: 'F7',  0x0042: 'F8',
    0x0043: 'F9',  0x0044: 'F10', 0x0085: 'F11', 0x0086: 'F12',
    0xE048: 'Up',    0xE050: 'Down',  0xE04B: 'Left',  0xE04D: 'Right',
    0xE047: 'Home',  0xE04F: 'End',   0xE049: 'PgUp',  0xE051: 'PgDn',
    0xE052: 'Insert',0xE053: 'Delete',
}

互動式測試程式


def main():
    print("按鍵測試模式 (ESC 退出)")
    print("格式: 類型 | 碼值 | 名稱")
    print("-" * 40)
    
    while True:
        ktype, kcode = get_key()
        if ktype is None:
            continue
        
        if ktype == 'char':
            if kcode == 27:  # ESC
                print("退出")
                break
            name = chr(kcode) if 32 <= kcode <= 126 else "Non-printable"
            print("CHAR  | %3d | %s" % (kcode, name))
        elif ktype == 'function':
            name = KEY_MAP.get(kcode, "Unknown")
            print("FUNC  | %5d | %s" % (kcode, name))
        elif ktype == 'ctrl':
            name = "Ctrl+%c" % (kcode + 64)  # 1->A, 2->B...
            print("CTRL  | %3d | %s" % (kcode, name))

if __name__ == '__main__':
    main()

跨平台替代方案

msvcrt 僅限 Windows。跨平台建議使用:

  • Windows:msvcrt (標準庫)、pynput (第三方)
  • Linux/macOS:curses、readchar、pynput
  • 統一介面:pynput.keyboard.Listener 事件驅動模式,支援所有平台

pynput 範例


from pynput import keyboard

def on_press(key):
    try:
        print('字元鍵:', key.char)
    except AttributeError:
        print('特殊鍵:', key)

with keyboard.Listener(on_press=on_press) as listener:
    listener.join()

應用場景

  • 文字模式選單導航 (方向鍵 + Enter)
  • 遊戲鍵盤控制
  • 快捷鍵綁定工具
  • 自動化測試腳本模擬按鍵
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved