You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下Python开发游戏:如何从/dev/input获取正常的鼠标输入?

解决双鼠标中键触发右键的问题

问题根源

中键触发时同时触发右键,通常是因为事件处理时错误匹配了按键码,或者没有正确区分BTN_MIDDLE(中键)和BTN_RIGHT(右键)的事件标识。evdev库中,鼠标三个按键的标准码分别是:

  • 左键:BTN_LEFT(代码272)
  • 右键:BTN_RIGHT(代码273)
  • 中键:BTN_MIDDLE(代码274)

解决方案步骤

  1. 修正设备选择逻辑:确保正确获取并保存两个鼠标的InputDevice实例,而非仅输入数字
  2. 精准解析事件:读取事件时严格区分按键类型和对应按键码,避免混淆中键和右键
  3. 多设备异步监听:用线程分别监听两个鼠标的事件,防止单线程阻塞导致事件丢失或误判

完整代码示例

import evdev
import threading

def get_mouse_device(prompt):
    # 列出所有输入设备
    devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
    print("\n当前可用输入设备:")
    for idx, device in enumerate(devices):
        print(f"[{idx}] {device.path} - {device.name}")
    
    # 获取用户选择
    while True:
        try:
            choice = int(input(f"\n{prompt}(输入设备序号):"))
            if 0 <= choice < len(devices):
                return devices[choice]
            else:
                print("序号超出范围,请重新输入")
        except ValueError:
            print("请输入有效的数字序号")

def listen_mouse(device):
    print(f"\n开始监听设备:{device.name} ({device.path})")
    for event in device.read_loop():
        # 处理移动事件
        if event.type == evdev.ecodes.EV_REL:
            if event.code == evdev.ecodes.REL_X:
                print(f"[{device.name}] X轴移动:{event.value}")
            elif event.code == evdev.ecodes.REL_Y:
                print(f"[{device.name}] Y轴移动:{event.value}")
        # 处理按键事件
        elif event.type == evdev.ecodes.EV_KEY:
            key_code = event.code
            key_state = "按下" if event.value == 1 else "释放"
            if key_code == evdev.ecodes.BTN_LEFT:
                print(f"[{device.name}] 左键{key_state}")
            elif key_code == evdev.ecodes.BTN_RIGHT:
                print(f"[{device.name}] 右键{key_state}")
            elif key_code == evdev.ecodes.BTN_MIDDLE:
                print(f"[{device.name}] 中键{key_state}")
            # 可添加其他按键处理(如侧键)

# 获取两个鼠标设备
mouse1 = get_mouse_device("选择第一个鼠标")
mouse2 = get_mouse_device("选择第二个鼠标")

# 启动线程分别监听两个鼠标
threading.Thread(target=listen_mouse, args=(mouse1,), daemon=True).start()
threading.Thread(target=listen_mouse, args=(mouse2,), daemon=True).start()

# 保持主程序运行
input("\n按回车键退出程序...\n")

关键说明

  • 直接通过evdev.ecodes调用标准按键码,避免手动写数字导致的错误
  • 用线程分离两个设备的监听逻辑,确保每个鼠标的事件都能被及时处理
  • 明确区分按键按下(value=1)和释放(value=0)的状态,避免重复触发误判

内容的提问来源于stack exchange,提问作者Boblet67

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:15:18