与 Xbox 控制器的 GUI 交互

     2023-02-16     62

关键词:

【中文标题】与 Xbox 控制器的 GUI 交互【英文标题】:GUI Interaction with Xbox Controller 【发布时间】:2021-05-17 21:03:09 【问题描述】:

我希望能够使用使用 QT 设计器创建的 PyQt5 在一个非常简单的 GUI 上显示 Xbox 控制器事件。 我正在使用xbox360controller Python 包将控制器与我的 Python 接口进行通信。以下示例代码可以正常工作,而不是打印值,我想在 GUI 上的唯一标签上设置文本:

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

这是简单的图形用户界面:

我的想法是这样的,但我很迷茫:

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_())

(我使用的是 Ubuntu 18.04)

【问题讨论】:

【参考方案1】:

您有 2 个错误:

第一个是self.controller.button_a.when_pressed = on_button_pressed()等价于value = on_button_pressed()self.controller.button_a.when_pressed = value,所以你没有分配回调但你已经分配了None,因为这是函数返回的。

即使您更正了上述问题,也会出现另一个错误:回调是在辅助线程中调用的,因此总而言之,您将从另一个线程修改 GUI,这是 Qt 禁止的。在这种情况下,解决方案是使用 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()

【讨论】:

你成就了我的一天。再次感谢您的好先生! @FelipeMedLev 那个错误?把完整的错误信息。我指出这一点是因为在您指出异常的 2 个 cmets 中,两条消息之间没有重合 @FelipeMedLev 我已经看到了错误,我已经更正了,再次测试。 Veo que hablas español! Para dejar el código perfecto sólo faltaría agregarle la 'b' de button en el prime for loop。感谢大师! Te dejé un cafecito ;) 嘿!我认为代码有效,因为它没有错误,但现在我正在测试,我意识到一个奇怪的行为。当我在操纵杆上移动 axis_r 时,显示屏上显示轴 trigger_r 已移动。当我移动轴 trigger_left 时,它表明我正在移动右触发器,当我移动轴 trigger_right 时,它表明 axis_r 仅在垂直轴上移动。

适用于 Xbox 360 控制器的振动 API

】适用于Xbox360控制器的振动API【英文标题】:vibrationapiforxbox360controller【发布时间】:2014-05-0410:18:46【问题描述】:有什么方法可以让VibrationAPI与Xbox360控制器一起工作?或者任何其他方式让它与javascript一起隆隆声?这是一个用j... 查看详情

subprocess.call() 与 GUI (Tkinter) 交互

】subprocess.call()与GUI(Tkinter)交互【英文标题】:subprocess.call()interactingwithGUI(Tkinter)【发布时间】:2012-06-0901:03:15【问题描述】:有没有办法使用subprocess.call()或subprocess.Popen()并通过Tkinter的Entry小部件与标准输入进行交互,并将标准... 查看详情

与 QMainWindow 的 GUI 命令交互时,QDockWidget 无法正确调整大小

】与QMainWindow的GUI命令交互时,QDockWidget无法正确调整大小【英文标题】:QDockWidgetdoesnotresizeproperlywheninteractingwithGUIcommandsofQMainWindow【发布时间】:2019-03-1200:39:08【问题描述】:我有一个关于QDockWidget的不正确调整大小的问题。特... 查看详情

在长时间处理期间与 GUI 交互

】在长时间处理期间与GUI交互【英文标题】:InteractingwithGUIduringlongprocessing【发布时间】:2012-11-0113:45:14【问题描述】:我有一个类层次结构:类BaseProcess公共虚拟无效执行()=0;;类子进程:BaseProcess公共虚拟无效执行()//做... 查看详情

与 Roblox 中的块和 ScreenGui 交互的问题

】与Roblox中的块和ScreenGui交互的问题【英文标题】:TroublewithinteractionwithblocksandScreenGuiinRoblox【发布时间】:2014-01-0305:01:15【问题描述】:我需要有关Roblox中“ScreenGui”对象的帮助。我正在尝试编写代码,当玩家通过gui点击一个... 查看详情

gui即人机交互图形化用户界面设计

GUI即人机交互图形化用户界面设计。纵观国际相关产业在图形化用户界面设计方面的发展现状,许多国际知名公司早已意识到GUI在产品方面产生的强大增值功能,以及带动的巨大市场价值,因此在公司内部设立了相关部门专门从... 查看详情

丢弃tkinter,这款gui神器值得拥有!

文| 闲欢来源:Python技术「ID:pythonall」GUI是一个人机交互的界面,换句话说,它是人类与计算机交互的一种方法。GUI主要使用窗口,图标和菜单,也可以通过鼠标和键盘进行操作。GUI库包含部件。部件是一系... 查看详情

C# 中 XBOX 控制器的事件处理程序?

】C#中XBOX控制器的事件处理程序?【英文标题】:EventHandlerforXBOXControllerinC#?【发布时间】:2014-04-1216:40:03【问题描述】:如果按下“A”按钮,我想使用XBOX360控制器播放声音。在我的代码片段中,我使用了一个while循环来检查按... 查看详情

如何在 Python 中记录 xbox/gamepad 控制器的状态?

】如何在Python中记录xbox/gamepad控制器的状态?【英文标题】:Howtorecordstateofxbox/gamepadcontrollerinPython?【发布时间】:2018-12-1615:39:47【问题描述】:我需要在特定时间知道一个xbox控制器的所有按钮的值。原因是我正在为神经网络构... 查看详情

C++ XInput 和 XBOX 360 控制器从不连接

】C++XInput和XBOX360控制器从不连接【英文标题】:C++XInputandXBOX360controllerneverconnects【发布时间】:2016-12-0906:04:28【问题描述】:我正在尝试连接XBOX360控制器以获取程序的输入,但我的程序永远不会注册连接的控制器--我已确认控... 查看详情

与后面的视图控制器交互

】与后面的视图控制器交互【英文标题】:Interactingwiththeviewcontrollerbehind【发布时间】:2017-06-0811:59:50【问题描述】:我知道SE上有几篇与此问题相关的帖子,但我无法绕过它们来找到适合我情况的解决方案。我在视图控制器中... 查看详情

xboxgamedvr怎么关闭

...能力,与个人电脑架构相似。微软的Kinect不需要使用任何控制器,它依靠相机捕捉三维空间中玩家的运动。微软指出它会让系统更加简易操作来吸引大众。这个系统也辨识人脸,让玩家自动连上游戏。它还可辨认声音和接受命令... 查看详情

在 Pygame 中无法检测到 Xbox 控制器的移动

】在Pygame中无法检测到Xbox控制器的移动【英文标题】:CannotdetectXboxcontrollermovementsinPygame【发布时间】:2017-05-0220:55:56【问题描述】:我一直使用pygame作为创建游戏的一种方式,我想将控制器游戏玩法融入游戏中。我一直在pygame... 查看详情

使用 Daydream 控制器作为指针与 Unity UI 交互

】使用Daydream控制器作为指针与UnityUI交互【英文标题】:InteractingwithUnityUIusingdaydreamcontrollerasapointer【发布时间】:2016-12-0618:23:49【问题描述】:我知道GazeInputModule,它允许用户使用头部移动与Unity的UI系统进行交互。我想知道是... 查看详情

旧 GamePadState xbox 控制器

】旧GamePadStatexbox控制器【英文标题】:OldGamePadStatexboxcontroller【发布时间】:2013-06-0218:42:32【问题描述】:所以我尝试使用以前使用键盘完成的游戏手柄来做一些非常简单的事情。那就是创建一个旧状态来记录上次更新时按下了... 查看详情

Qt GUI 应用程序在与 gui 交互时停止实时进程

】QtGUI应用程序在与gui交互时停止实时进程【英文标题】:QtGUIapplicationstopsrealtimeprocesswheninteractingwithgui【发布时间】:2016-12-3114:25:13【问题描述】:我有一个QtGUI应用程序,它正在做一些重要的实时工作,不能不惜一切代价中断... 查看详情

在 MVC 模式的 GUI 应用程序中,可以、应该以及如何最好地将控制器与 GUI 布局隔离?

...在MVC模式的GUI应用程序中,可以、应该以及如何最好地将控制器与GUI布局隔离?【英文标题】:InanMVCpatternedGUIapplication,can,should,andhowcanonebestisolatethecontrollersfromtheGUIlayout?【发布时间】:2021-04-0907:40:31【问题描述】:我一直在摆弄... 查看详情

使用 XInput 和 VB.NET 支持 xbox 360 控制器

】使用XInput和VB.NET支持xbox360控制器【英文标题】:UseXInputandVB.NETforxbox360controllersupport【发布时间】:2014-01-2423:49:02【问题描述】:我想知道是否有人可以在xinput(for和Xbox控制器)和vb.net方面给我一点帮助。我想要做的是将模拟... 查看详情