I am currently on a project where I have to use Tkinter to make a game, and I would like to be able to move stuff on a canvas in Tkinter (like moving a circle with a ps4 controller's joystick for example). In this project, it is mandatory that I use tkinter to make the UI of the game, so I needed a python module to handle my PS4 controller. I chose to go for PyPS4Controller
But there are two event loops : tkinter.mainloop() from the Tkinter module and controller.listen() from the PyPS4Controller module.
I'm really lost. Your help is much appreciated. Thanks ! ;D
Edit:
Further down is the code I came up with to showcase my problem, along with the live result in the console. Even with the pyPS4Controller event loop inside a thread, my program is still stuck, waiting for an input
import tkinter as tk
from pyPS4Controller.controller import Controller
import threading
# The list the will contain all events related to the PS4 controller
eventQueue = []
# Function to launch a thread, for appending
# user inputs to the eventQueue
class getPS4Input(threading.Thread):
def __init__(self, controller):
threading.Thread.__init__(self)
self.controller = controller
def start(self):
# No more visible loop, it is already in controller.listen
self.controller.listen()
# All events that are related to the controller are handled by
# this class (a pyPS4Controller module specific class)
class MyController(Controller):
def __init__(self, **kwargs):
Controller.__init__(self, **kwargs)
# On the X button is pressed
def on_R3_right(self, value):
# Append the new value for the xaxis along with a tag used to
# understand what the value is for
eventQueue.append(('R3_xaxis', value))
# Other events (none here for exemple purposes)
# The object that needs to be moved around
# Here its purpose is to have a way to know if the R3_xaxis value
# has been modified
class ball():
def __init__(self):
self.R3_xaxis = 0
def show(self):
print(self.R3_xaxis)
# The function to be called periodically by tkinter
# to update here just the R3_xaxis, example purposes
def checkEventQueue(ball):
while (eventQueue != []):
# Get new events until there is none left
[eventTag, eventValue] = eventQueue.pop()
# Update the R3_xaxis value for the object ball
if (eventTag == 'R3_xaxis'):
ball.R3_xaxis = eventValue
# Repeat the check every 200 ms
root.after(200, lambda:checkEventQueue(ball))
# The controller, view as an object by Python
controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False)
root = tk.Tk()
# A button, just to see if the tkinter loop is running correctly (not stopped)
tk.Button(root, text ="Hello", command=lambda:print("Bouton TK appuyé")).pack()
# Initialize the thread to get user inputs
t = getPS4Input(controller)
t.start()
# Check for user inputs entered in the last 200 ms
root.after(200, lambda:checkEventQueue(ball))
# The Tk event loop
tk.mainloop()
Here is the live program result, as you can see, it is waiting for an input (actually for a controller to be connected, but you see my point, I don't want to be stuck here, I want to get to the Tk mainloop)
Waiting for interface: /dev/input/js0 to become available . . .
Thanks for the help.