pythonpysimpleguievdev

PySimpleGUI and custom usb joystick input


I am trying to make an arcade style user guided story book terminal using PySimpleGUI and a custom made usb joystick providing the input. I have created a PySimpleGUI imageloader with the button prompts. Image viewer:

import io
import os
import PySimpleGUI as sg
from PIL import Image

image = Image.open("/path/to/file.jpg")
image.thumbnail((200, 200))
bio = io.BytesIO()
image.save(bio, format="PNG")

layout = [[sg.Image(key="-IMAGE-")],
          [sg.Button("Green"),
           sg.Button("Blue"),]
          ]
window = sg.Window("Image Viewer", layout, finalize=True)
window["-IMAGE-"].update(data=bio.getvalue())

while True:

    event, values = window.read()
    if event == "Exit" or event == sg.WIN_CLOSED:
        break
    if event == "Green":
        load_image_str = "g"
    if event == "Blue":
        load_image_str = "b"

    file_path = ("/path/to/folder" + load_image_str + ".jpg")

    if os.path.exists(file_path) and file_path.endswith('.jpg'):
        image = Image.open("/path/to/file")
        image.thumbnail((400, 400))
        bio = io.BytesIO()
        image.save(bio, format="PNG")
        window["-IMAGE-"].update(data=bio.getvalue())

window.close()

Joystick input

from evdev import InputDevice, ecodes

#Button codes
greenBtn = 288
blueBtn = 289

device = InputDevice('/dev/input/eventXX')

def main():
    for event in device.read_loop():
        if event.type == ecodes.EV_KEY:
            if event.value == 1:
                if event.code == greenBtn:
                    print("green")
                if event.code == blueBtn:
                    print("blue")


if __name__ == "__main__":
    x =main()

The image viewer and the joystick are working as I expected but I don't know where to even start combining the two. Am I on the right track here or should I be looking at a different way to do this?


Solution

  • If you use a thread for the joystick part, then your GUI can wait on Joystick events and handle them or handle events from the GUI itself.

    import PySimpleGUI as sg
    import time
    import random
    
    # thread for joystick handling
    def joystick_thread(window):
        while True:
            time.sleep(1)                # Replace with your read joystick code
    
            # If got some kind of joystick event
            value = random.randint(200, 250)
            window.write_event_value(('-JOYSTICK-', '-EV KEY-'), value)
    
    # The GUI Portion
    def main():
        layout = [  [sg.Text('Joystick Monitor Window')],
                    [sg.Text(key='-OUT-')],
                    [sg.Button('Does Nothing'), sg.Button('Exit')]  ]
    
        window = sg.Window('Joystick', layout, finalize=True)
        
        # Startup the joystick thread
        window.start_thread(lambda: joystick_thread(window), ('-JOYSTICK-', '-ENDED-'))
    
        while True:             # Event Loop
            event, values = window.read()
            print(event, values)
            if event == sg.WIN_CLOSED or event == 'Exit':
                break
    
            if event[0] == '-JOYSTICK-':
                if event[1] == '-ENDED-':
                    break
                if event[1] == '-EV KEY-':
                    window['-OUT-'].update(f'Joystick event received {values[event]}')
        window.close()
    
    if __name__ == '__main__':
        main()
    
    

    enter image description here