简体   繁体   English

与 Xbox Controller 的 GUI 交互

[英]GUI Interaction with Xbox Controller

I'd like to be able to show Xbox controller events on a very simple GUI using PyQt5 which was created using the QT Designer.我希望能够使用 PyQt5 在一个非常简单的 GUI 上显示 Xbox controller 事件,该 GUI 是使用 QT 设计器创建的。 I'm using xbox360controller Python package to communicate the controller with my Python interface. I'm using xbox360controller Python package to communicate the controller with my Python interface. The following example code works as it should, and instead of printing the values I'd like to set the text on the only label on the GUI:以下示例代码可以正常工作,而不是打印值,我想在 GUI 上的唯一 label 上设置文本:

import signal
from xbox360controller import Xbox360Controller


def on_button_pressed(button):
    print('Button {0} was pressed'.format(button.name))


def on_button_released(button):
    print('Button {0} was released'.format(button.name))


def on_axis_moved(axis):
    print('Axis {0} moved to {1} {2}'.format(axis.name, axis.x, axis.y))

try:
    with Xbox360Controller(0, axis_threshold=0.2) as controller:
        # Button A events
        controller.button_a.when_pressed = on_button_pressed
        controller.button_a.when_released = on_button_released

        # Left and right axis move event
        controller.axis_l.when_moved = on_axis_moved
        controller.axis_r.when_moved = on_axis_moved

        signal.pause()
except KeyboardInterrupt:
    pass

This is the simple GUI:这是简单的图形用户界面:

在此处输入图像描述

My idea was something like this, but I'm very lost:我的想法是这样的,但我很迷茫:

class MainWindow(Ui_MainWindow, Ui_MainClass):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.controller = Xbox360Controller(0, axis_threshold=0.2)
        self.controller.button_a.when_pressed = on_button_pressed()
        self.controller.button_a.when_released = on_button_released()

        # Left and right axis move event
        self.controller.axis_l.when_moved = on_axis_moved
        self.controller.axis_r.when_moved = on_axis_moved

    def on_button_pressed(self, button):
        print('Button {0} was pressed'.format(button.name))
        self.label_joy.setText(f'Button {0} was pressed'.format(button.name))

    def on_button_released(self, button):
        print('Button {0} was released'.format(button.name))
        self.label_joy.setText(f'Button {0} was released'.format(button.name))

    def on_axis_moved(self, axis):
        print('Axis {0} moved to {1} {2}'.format(axis.name, axis.x, axis.y)) 
        self.label_joy.setText('Axis {0} moved to {1} {2}'.format(axis.name, axis.x, axis.y))    
    

if __name__ == "__main__":
    app = QApplication([])
    form = MainWindow()
    form.show()
    sys.exit(app.exec_())

(I'm using Ubuntu 18.04) (我使用的是 Ubuntu 18.04)

You have 2 errors:您有 2 个错误:

  • The first is that self.controller.button_a.when_pressed = on_button_pressed() is equivalent to value = on_button_pressed() self.controller.button_a.when_pressed = value , so you have not assigned the callback but you have assigned None since that is what the function returns.第一个是self.controller.button_a.when_pressed = on_button_pressed()等价于value = on_button_pressed() self.controller.button_a.when_pressed = value None 因为你没有分配回调但你已经分配了什么function 返回。

  • Even if you correct the above, there is also another error: callbacks are invoked in a secondary thread, so in conclusion you would be modifying the GUI from another thread, which Qt prohibits.即使您更正了上述内容,也会出现另一个错误:回调是在辅助线程中调用的,因此总而言之,您将从另一个线程修改 GUI,这是 Qt 禁止的。 In this case the solution is to use the Qt signals to transmit the information since they are thread-safe.在这种情况下,解决方案是使用 Qt 信号来传输信息,因为它们是线程安全的。

import sys
from functools import cached_property

from PyQt5 import QtCore, QtWidgets

from xbox360controller import Xbox360Controller
from xbox360controller.controller import Button, Axis, RawAxis


class Controller(QtCore.QObject):
    button_pressed = QtCore.pyqtSignal(Button)
    button_released = QtCore.pyqtSignal(Button)

    axis_moved = QtCore.pyqtSignal(object)

    def __init__(self, parent=None):
        super().__init__(parent)

        try:
            self.Xbox360_controller
        except Exception as e:
            print(e)
            sys.exit(-1)

        for button in self.Xbox360_controller.buttons:
            button.when_pressed = self._on_button_pressed
            button.when_released = self._on_button_released

        for axis in self.Xbox360_controller.axes:
            axis.when_moved = self._on_axis_moved

    @cached_property
    def Xbox360_controller(self):
        return Xbox360Controller(0, axis_threshold=0.2)

    def _on_button_pressed(self, button):
        self.button_pressed.emit(button)

    def _on_button_released(self, button):
        self.button_released.emit(button)

    def _on_axis_moved(self, axis):
        self.axis_moved.emit(axis)

    def close(self):
        self.Xbox360Controller.close()


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
        self.setCentralWidget(self.label)

    def handle_button_pressed(self, button):
        self.label.setText(f"Button {button.name} was pressed")

    def handle_button_released(self, button):
        self.label.setText(f"Button {button.name} was released")

    def handle_axis_moved(self, axis):
        if isinstance(axis, Axis):
            self.label.setText(f"Axis {axis.name} moved to {axis.x} {axis.y}")
        elif isinstance(axis, RawAxis):
            self.label.setText(f"Axis {axis.name} moved to {axis.value}")


def main():
    app = QtWidgets.QApplication(sys.argv)

    w = MainWindow()
    w.show()

    controller = Controller()
    controller.button_pressed.connect(w.handle_button_pressed)
    controller.button_released.connect(w.handle_button_released)
    controller.axis_moved.connect(w.handle_axis_moved)

    ret = app.exec_()

    controller.close()

    sys.exit(ret)


if __name__ == "__main__":
    main()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM