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

Ubuntu虚拟机下用Python向其他程序发送游戏手柄输入的实现方案

Sending Gamepad/Joystick Inputs via Python on Ubuntu (VM)

Hey there, let's break down how to send gamepad inputs with Python on your Ubuntu VM—this aligns with the DirectInput approach you mentioned for keyboard/mouse, but tailored specifically for controllers. Linux uses the evdev subsystem instead of DirectInput, so we'll leverage that with the evdev Python library.

Prerequisites

First, get the tools and permissions sorted:

  • Install the evdev library:
    pip install evdev
    
  • Grant permission to access input devices: You'll need to add your user to the input group to avoid running scripts with sudo every time:
    sudo usermod -aG input $USER
    
    Log out and back in for this change to take effect.
  • VM Note: Make sure your physical gamepad (if using one) is passed through to the Ubuntu VM. For VirtualBox/VMware, go to the USB devices menu and select your controller to redirect it from the host to the guest.

Understand Gamepad Event Codes

Linux maps every gamepad button/axis to a specific event code. To find the codes for your controller (or reference standard ones), use the evtest tool:

  1. Install it:
    sudo apt install evtest
    
  2. Run it and select your gamepad from the list to see real-time event codes when you press buttons or move sticks. For example:
    • Left stick X-axis = ABS_X
    • X button (PS-style) = BTN_SOUTH
    • D-pad left/right = ABS_HAT0X

Python Script to Send Gamepad Inputs

We'll create a virtual gamepad using UInput (part of evdev) and send events to it. This works because most games/programs will recognize the virtual device as a real controller.

Here's a sample script that simulates stick movement and button presses:

from evdev import UInput, ecodes as e
import time

# Define the capabilities of our virtual gamepad (matches standard controllers)
gamepad_capabilities = {
    # Buttons: PS-style (X, Circle, Square, Triangle) + triggers, start/select
    e.EV_KEY: [
        e.BTN_SOUTH, e.BTN_EAST, e.BTN_WEST, e.BTN_NORTH,
        e.BTN_START, e.BTN_SELECT, e.BTN_MODE,
        e.BTN_TL, e.BTN_TR, e.BTN_TL2, e.BTN_TR2,
        e.BTN_THUMBL, e.BTN_THUMBR
    ],
    # Axes: Left/right sticks, triggers, D-pad
    e.EV_ABS: [
        (e.ABS_X, (0, 255, 0, 0)),    # Left stick X (0=left, 255=right)
        (e.ABS_Y, (0, 255, 0, 0)),    # Left stick Y (0=up, 255=down)
        (e.ABS_Z, (0, 255, 0, 0)),    # Right stick X
        (e.ABS_RZ, (0, 255, 0, 0)),   # Right stick Y
        (e.ABS_HAT0X, (-1, 1, 0, 0)), # D-pad X (-1=left, 1=right)
        (e.ABS_HAT0Y, (-1, 1, 0, 0))  # D-pad Y (-1=up, 1=down)
    ]
}

# Create the virtual gamepad device
with UInput(gamepad_capabilities, name="Python Virtual Gamepad") as virtual_gamepad:
    print("Virtual gamepad created. Sending test inputs...")

    # Simulate left stick moving fully right
    virtual_gamepad.write(e.EV_ABS, e.ABS_X, 255)
    virtual_gamepad.syn()  # Sync events to notify the system
    time.sleep(1)

    # Simulate pressing the X button (BTN_SOUTH)
    virtual_gamepad.write(e.EV_KEY, e.BTN_SOUTH, 1)  # 1 = press
    virtual_gamepad.syn()
    time.sleep(0.5)

    # Release the X button
    virtual_gamepad.write(e.EV_KEY, e.BTN_SOUTH, 0)  # 0 = release
    virtual_gamepad.syn()
    time.sleep(0.5)

    # Reset left stick to center position
    virtual_gamepad.write(e.EV_ABS, e.ABS_X, 127)
    virtual_gamepad.syn()
    time.sleep(1)

print("Test completed. Virtual gamepad closed.")

How It Works

  • UInput creates a virtual input device that the OS treats like a physical gamepad.
  • write() sends individual events (axis movement, button presses/releases).
  • syn() is critical: it tells the system that a full set of events is ready to be processed—without this, your inputs won't register.

Testing the Inputs

To verify the virtual gamepad is working:

  1. Run the script.
  2. Open a terminal and run:
    jstest /dev/input/jsX
    
    Replace X with the number of your virtual gamepad (you can find it with ls /dev/input/js*). You'll see the inputs update as the script runs.

Customizing for Your Use Case

  • Adjust the gamepad_capabilities to match the buttons/axes your target program expects.
  • Modify the write() calls to send specific inputs (e.g., hold a trigger, move the right stick) based on your needs.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:40:29