Python如何获取操纵杆输入?Mac端不使用PyGame的实现方案咨询
可行的替代方案及问题修复
修复inputs库报错(最低改造成本)
你遇到的inputs.UnpluggedError本质是Mac系统的权限限制导致的,并非设备真的未识别:
- 打开「系统偏好设置」→「安全性与隐私」→「隐私」选项卡
- 左侧列表选择「输入监控」,右侧勾选你运行Python程序的终端/IDE(如Terminal、VS Code、PyCharm)
- 重启程序后即可正常读取摇杆输入
inputs库读取罗技摇杆的示例代码如下:
import inputs # 枚举所有游戏控制器 devices = inputs.devices.gamepads if not devices: print("未检测到操纵杆") exit() joystick = devices[0] while True: events = joystick.read() for event in events: # 轴输入事件 if event.ev_type == "Absolute": print(f"轴{event.code} 值:{event.state}") # 按钮输入事件 elif event.ev_type == "Key": print(f"按钮{event.code} 状态:{bool(event.state)}")
方案2:使用pyhidapi直接访问HID设备(无GUI框架依赖)
如果不想用inputs库,可以用跨平台的HID设备访问库pyhidapi,直接读取摇杆原始数据:
安装步骤
- 先安装底层依赖:
brew install hidapi - 安装Python绑定:
pip install hidapi
示例代码
import hid # 罗技Extreme 3D Pro的VID和PID固定为0x046d和0xc215 VENDOR_ID = 0x046d PRODUCT_ID = 0xc215 try: joystick = hid.Device(vid=VENDOR_ID, pid=PRODUCT_ID) except Exception as e: print(f"设备打开失败:{e}") exit() print(f"已连接设备:{joystick.product}") while True: # 每次读取64字节原始数据 data = joystick.read(64) if data: # 解析规则可根据实际输出调整,不同轴对应不同字节位 print(f"原始数据:{[hex(x) for x in data]}")
方案3:Pygame与Tkinter共存(无需重写现有代码)
你不需要放弃已完成的Pygame原型,只要将摇杆监听逻辑放到独立的子线程运行,不要阻塞Tkinter的主线程,两者完全可以共存:
import tkinter as tk import threading import os import pprint import pygame # 你原有代码的控制器类 class PS4Controller(object): """Class representing the PS4 controller. Pretty straightforward functionality.""" controller = None axis_data = None button_data = None hat_data = None def init(self): """Initialize the joystick components""" pygame.init() pygame.joystick.init() self.controller = pygame.joystick.Joystick(0) self.controller.init() def listen(self): """Listen for events to happen""" if not self.axis_data: self.axis_data = {} if not self.button_data: self.button_data = {} for i in range(self.controller.get_numbuttons()): self.button_data[i] = False if not self.hat_data: self.hat_data = {} for i in range(self.controller.get_numhats()): self.hat_data[i] = (0, 0) while True: for event in pygame.event.get(): if event.type == pygame.JOYAXISMOTION: self.axis_data[event.axis] = round(event.value,2) elif event.type == pygame.JOYBUTTONDOWN: self.button_data[event.button] = True elif event.type == pygame.JOYBUTTONUP: self.button_data[event.button] = False elif event.type == pygame.JOYHATMOTION: self.hat_data[event.hat] = event.value def controller_main(): ps4 = PS4Controller() ps4.init() ps4.listen() def tkinter_main(): root = tk.Tk() root.title("Tkinter主窗口") label = tk.Label(root, text="和Pygame摇杆监听共存") label.pack() root.mainloop() if __name__ == "__main__": # 摇杆监听跑在子线程 joystick_thread = threading.Thread(target=controller_main, daemon=True) joystick_thread.start() # Tkinter跑在主线程 tkinter_main()
内容的提问来源于stack exchange,提问作者user15002651
相关产品推荐
相关产品推荐

