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

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,直接读取摇杆原始数据:

安装步骤

  1. 先安装底层依赖:brew install hidapi
  2. 安装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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:57:03