使用Kivy调用pygame游戏杆数据收集

时间:2020-07-15 01:59:57

标签: python python-3.x pygame kivy

好的,所以我一直在尝试调用一个函数,该函数使用pygame.joystick从2个Logitech 3d Extreme Pro游戏杆中获取输入。当我严格使用pygame时,操纵杆将被识别并正常工作。但是当我尝试在kv语言中调用类似的函数时,会出现此错误。

   File "MainUI__1-2.py", line 179, in <module>
     MainClass().run()
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/app.py", line 829, in run
     root = self.build()
   File "MainUI__1-2.py", line 175, in build
     return tabpanelkv()
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/uix/tabbedpanel.py", line 482, in __init__
     super(TabbedPanel, self).__init__(**kwargs)
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/uix/gridlayout.py", line 256, in __init__
     super(GridLayout, self).__init__(**kwargs)
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/uix/layout.py", line 76, in __init__
     super(Layout, self).__init__(**kwargs)
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/uix/widget.py", line 361, in __init__
     rule_children=rule_children)
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/uix/widget.py", line 469, in apply_class_lang_rules
     rule_children=rule_children)
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/lang/builder.py", line 538, in apply
     rule_children=rule_children)
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/lang/builder.py", line 659, in _apply_rule
     child, crule, rootrule, rule_children=rule_children)
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/lang/builder.py", line 659, in _apply_rule
     child, crule, rootrule, rule_children=rule_children)
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/lang/builder.py", line 654, in _apply_rule
     child = cls(__no_builder=True)
   File "MainUI__1-2.py", line 129, in __init__
     self.Joy1B = pygame.joystick.Joystick(self.joy1A)
 TypeError: an integer is required (got type NoneType)

但是我给那条线一个整数。下面的代码是我目前试图开始工作的代码。我正在使用的操纵杆位于位置0和1(pygame不在计算机上)。这是我的代码:

# Main Code for control code
# Kivy for front end UI
# pygame for backend Joystick code
# opencv for camera control

# 1. Import necessary libraries
# 1.1 Kivy libraries and imports
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.lang import Builder
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.properties import ObjectProperty, NumericProperty


# 1.2 other libraries needed that are not a part of kivy
import cv2
import numpy as np
import pygame
from pygame.locals import *
import serial
import time

# 2. Variables (declared after structural code is done)
pygame.init()
pygame.joystick.init()

Lateral_X_Y = 0
Vertical_Z = 0
S1_Data = 0
S2_Data = 0
S3_Data = 0
S4_Data = 0
Lights = 0

In_Min = float(-1)
In_Max = float(1)
Out_Min = float(1000)
Out_Max = float(2000)
Scaled_Out_Min = float(1250)
Scaled_Out_Max = float(1750)

startMarker = '<'
endMarker = '\n'
dividingmarker = ','

# arduino = serial.Serial(port="COM14", baudrate=115200, timeout=0.01)
time.sleep(.01)

Builder.load_string("""

<tabpanelkv>:
    size_hint: 1, 1
    pos_hint: {'center_x': .5, 'center_y': .5}
    do_default_tab: False

    TabbedPanelItem:
        text: 'Cameras'
        GridLayout:
            rows: 1
            cols: 2
            GridLayout:
                size_hint: 1.7, 1
                rows: 1
                cols: 1
                KivyCamera:
                    cam: 0
            GridLayout:
                rows: 2
                cols: 1
                KivyCamera:
                    cam: 2
                Button:
                    text: 'Cam3'

    TabbedPanelItem:
        text: 'Diagnostics'
        GridLayout:
            rows: 4
            cols: 1
            JoystickValue:
                joy1A: 0
                joy2A: 1

""")

class KivyCamera(Image):
    cam = ObjectProperty()
    fps = NumericProperty(30)

    def __init__(self, **kwargs):
        super(KivyCamera, self).__init__(**kwargs)
        self._capture = None
        if self.cam is not None:
            self._capture = cv2.VideoCapture(self.cam)
        Clock.schedule_interval(self.update, 1.0 / self.fps)

    def on_cam(self, *args):
        if self._capture is not None:
            self._capture.release()
        self._capture = cv2.VideoCapture(self.cam)

    @property
    def capture(self):
        return self._capture

    def update(self, dt):
        ret, frame = self.capture.read()
        if ret:
            buf1 = cv2.flip(frame, 0)
            buf = buf1.tostring()
            image_texture = Texture.create(
                size=(frame.shape[1], frame.shape[0]), colorfmt="bgr"
            )
            image_texture.blit_buffer(buf, colorfmt="bgr", bufferfmt="ubyte")
            self.texture = image_texture

class JoystickValue(GridLayout):
    joy1A = ObjectProperty()
    joy2A = ObjectProperty()
    def __init__(self, **kwargs):
        super(JoystickValue, self).__init__(**kwargs)
        self.Joy1B = pygame.joystick.Joystick(self.joy1A)
        self.Joy2B = pygame.joystick.Joystick(self.joy2A)

        self.Joy1B.init()
        self.Joy2B.init()
        self.Xmovdata = ObjectProperty()
        self.Ymovdata = ObjectProperty()
        self.Zmovdata = ObjectProperty()
        self.Userdata = ObjectProperty()
        self.TserData = ObjectProperty()
        self.OserData = ObjectProperty()
        self.CTserData = ObjectProperty()
        self.StupidFuck = ObjectProperty()

    def JoyRead(self):
        self.Joy1X = self.Joy1B.get_axis(0)
        self.Joy1Y = self.Joy1B.get_axis(1)

        self.Joy2X = self.Joy2B.get_axis(0)
        self.Joy2Y = self.Joy2B.get_axis(1)

        # Buttons on Joy1: 2,3,6,7,8,9,10
        self.Joy1B2 = self.Joy1B.get_button(1)
        self.Joy1B3 = self.Joy1B.get_button(2)
        self.Joy1B6 = self.Joy1B.get_button(5)
        self.Joy1B7 = self.Joy1B.get_button(6)
        self.Joy1B8 = self.Joy1B.get_button(7)
        self.Joy1B9 = self.Joy1B.get_button(8)
        self.Joy1B10 = self.Joy1B.get_button(9)

        # Buttons for Joy2: 1, 6
        self.Joy2B1 = self.Joy2B.get_button(0)
        self.Joy2B6 = self.Joy2B.get_button(5)

        # Hat switch for Joy1
        self.Joy1HF = self.Joy1B.get_hat(0)

        print(str(self.Joy1X))

# 5. tabpanelkv class
class tabpanelkv(TabbedPanel):
    pass

# 6. Main Class
class MainClass(App, GridLayout):
    def build(self):
        return tabpanelkv()

# 7. Main Loop
if __name__ == '__main__':
    MainClass().run()

我已经使相机正常工作,但是现在操纵杆给了我一些问题。我最终将输出的数据输出到第二个选项卡(到这一步很简单。如果您有任何建议对它们进行注释),在此刻,我们将提供任何帮助。在过去的几个小时中,我一直在努力使它工作(尝试不同的想法)。 我尝试过的想法:

  1. 在这些行 self.Joy1B = pygame.joystick.Joystick(self.joy1A) self.Joy2B = pygame.joystick.Joystick(self.joy2A)中将self.Joy1A和self.Joy2A更改为直线0和1。但是,我无法调用后面的JoyRead()函数。 (至少我认为我做不到,我可能错了)
  2. 采用选项1,然后在代码中稍后调用该函数(老实说,我忘记了从哪里调用该函数)。
  3. 与朋友协商以尝试找到解决方案。
  4. 将pygame.joystick.Joystick行放入if语句中,如下所示:
        if self.joy1A is not None or self.joy2A is not None:
            self.Joy1B = pygame.joystick.Joystick(self.joy1A)
            self.Joy2B = pygame.joystick.Joystick(self.joy2A)

一如既往地感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

问题是__init__Kivy执行kv之前执行。

您可以直接在代码中设置值

class JoystickValue(GridLayout):

    joy1A = ObjectProperty(0)
    joy2A = ObjectProperty(1)

或者您必须稍后使用sheduler来运行此代码,而Kivy将有时间执行kv

class JoystickValue(GridLayout):

    joy1A = ObjectProperty()
    joy2A = ObjectProperty()
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        #print('self.joy1A:', self.joy1A)
        
        Clock.schedule_once(self.set_joys, 0.1)

    def set_joys(self, arg):

        #print('self.joy1A:', self.joy1A)
        
        self.Joy1B = pygame.joystick.Joystick(self.joy1A)
        self.Joy2B = pygame.joystick.Joystick(self.joy2A)

        # ... rest ...