'How to Get Input from Joystick in Python?

I'm trying to get input from a joystick I have (specifically the Logitech Extreme 3D Pro) with a Python program. Unfortunately, I do not know how to do this well.

I currently have a working prototype using PyGame, but I do not want to use PyGame because I already want another Tkinter window open at the same time.

I've tried the inputs library, but I keep getting an inputs.UnpluggedError every time I plug the joystick in.

Are there any other methods of getting joystick input, other than PyGame?

I am using an MacBook Air running Big Sur.

Working code:

import os
import pprint
import pygame
import threading

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

                # Insert your code on what you would like to happen for each event here!
                # In the current setup, I have the state simply printing out to the screen.
                
                os.system('clear')
                pprint.pprint(self.button_data)
                pprint.pprint(self.axis_data)
                pprint.pprint(self.hat_data)


def controller_main():
    ps4 = PS4Controller()
    ps4.init()
    ps4.listen()

controller_main()


Solution 1:[1]

Try this py-joystick module: https://pypi.org/project/pyjoystick/ Hope it helps!?

from pyjoystick.sdl2 import Key, Joystick, run_event_loop

def print_add(joy):
    print('Added', joy)

def print_remove(joy):
    print('Removed', joy)

def key_received(key):
    print('received', key)
    if key.value == Key.HAT_UP:
        #do something
    elif key.value == Key.HAT_DOWN:
        #do something
    if key.value == Key.HAT_LEFT:
        #do something
    elif key.value == Key.HAT_UPLEFT:
        #do something
    elif key.value == Key.HAT_DOWNLEFT:
        #do something
    elif key.value == Key.HAT_RIGHT:
        #do something
    elif key.value == Key.HAT_UPRIGHT:
        #do something
    elif key.value == Key.HAT_DOWNRIGHT:
        #do something

run_event_loop(print_add, print_remove, key_received)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1