0

好的,所以我一直在尝试调用一个函数,该函数使用 pygame.joystick 从 2 个 Logitech 3dextreme 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.Joy1A 和 self.Joy2A 更改 self.Joy1B = pygame.joystick.Joystick(self.joy1A) self.Joy2B = pygame.joystick.Joystick(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)

任何帮助一如既往地受到赞赏。

4

1 回答 1

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 ...
于 2020-07-15T05:03:01.283 回答