Cámara Kivy como widget de idioma KV

Estoy usando Kivy con una webcam. He seguido este ejemplo por @Arnav de usar opencv para formar y mostrar la cámara como un widget. He “extendido” el diseño dentro de python para agregar dos botones como prueba, en preparación para un diseño más complicado.

class CamApp(App): def build(self): self.capture = cv2.VideoCapture(0) self.my_camera = KivyCamera(capture=self.capture, fps=30,resolution=(1920,1080)) root = BoxLayout(orientation = 'vertical') root.add_widget(self.my_camera,1) box2 = BoxLayout(orientation = 'vertical') btn1 = Button(text='Hello world 1') btn2 = Button(text='Hello world 2') box2.add_widget(btn1) box2.add_widget(btn2) root.add_widget(box2, 0) return root #return Builder.load_string(kv) 

Mientras esto funciona, preferiría mover los componentes de la interfaz de usuario de python a un archivo de kv language . ¿El problema es saber cómo “describir” la self.my_camera en el archivo kv ?

No estoy seguro de si heredar la clase KivyCamera como un widget dentro del archivo kv , es decir

 kv = ''' : texture: self.my_camera resolution: (1920, 1080) pos: self.pos size: self.size 

O si utilizar el widget de canvas

 : canvas: Rectangle: source: self.my_camera pos: self.pos size: self.size 

He intentado otras implementaciones “pirateadas”, pero en todos los casos el problema es vincularse a través de self.my_camera en el archivo kv .

¿Alguna sugerencia?

Quizás este ejemplo pueda ayudarte.

 # Import 'kivy.core.text' must be called in entry point script # before import of cv2 to initialize Kivy's text provider. # This fixes crash on app exit. import kivy.core.text import cv2 from kivy.app import App from kivy.base import EventLoop from kivy.uix.image import Image from kivy.clock import Clock from kivy.graphics.texture import Texture from kivy.uix.boxlayout import BoxLayout from kivy.core.window import Window class KivyCamera(Image): def __init__(self, **kwargs): super(KivyCamera, self).__init__(**kwargs) self.capture = None def start(self, capture, fps=30): self.capture = capture Clock.schedule_interval(self.update, 1.0 / fps) def stop(self): Clock.unschedule_interval(self.update) self.capture = None def update(self, dt): return_value, frame = self.capture.read() if return_value: texture = self.texture w, h = frame.shape[1], frame.shape[0] if not texture or texture.width != w or texture.height != h: self.texture = texture = Texture.create(size=(w, h)) texture.flip_vertical() texture.blit_buffer(frame.tobytes(), colorfmt='bgr') self.canvas.ask_update() capture = None class QrtestHome(BoxLayout): def init_qrtest(self): pass def dostart(self, *largs): global capture capture = cv2.VideoCapture(0) self.ids.qrcam.start(capture) def doexit(self): global capture if capture != None: capture.release() capture = None EventLoop.close() class qrtestApp(App): def build(self): Window.clearcolor = (.4,.4,.4,1) Window.size = (400, 300) homeWin = QrtestHome() homeWin.init_qrtest() return homeWin def on_stop(self): global capture if capture: capture.release() capture = None qrtestApp().run() 

y el archivo kv:

 : BoxLayout: orientation: "vertical" Label: height: 20 size_hint_y: None text: 'Testing the camera' KivyCamera: id: qrcam BoxLayout: orientation: "horizontal" height: 20 size_hint_y: None Button: id: butt_start size_hint: 0.5,1 text: "start" on_press: root.dostart() Button: id: butt_exit text: "quit" size_hint: 0.5,1 on_press: root.doexit()