Kivy 相机作为 KV 语言小部件
Kivy Camera as KV language widget
我正在使用带网络摄像头的 Kivy。我跟随@Arnav this example 使用 opencv 来形成和显示相机作为一个小部件。我有"extended"里面的布局python,添加两个按钮作为测试,为更复杂的布局做准备。
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)
虽然这可行,但我更愿意将 UI 组件移出 python 并移入 kv language
文件。
问题是知道如何 "describe" kv
文件中的 self.my_camera
?
我不确定是否将 KivyCamera
class 作为 kv
文件中的 widget
继承,即
kv = '''
<Cam1@KivyCamera>:
texture: self.my_camera
resolution: (1920, 1080)
pos: self.pos
size: self.size
或者是否使用 canvas
小部件
<MyWidget>:
canvas:
Rectangle:
source: self.my_camera
pos: self.pos
size: self.size
我尝试了其他 "hacked" 实现,但在所有情况下,问题都是通过 self.my_camera
链接到 kv
文件。
有什么建议吗?
也许这个例子可以帮到你。
# 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()
和 kv 文件:
<QrtestHome>:
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()
我正在使用带网络摄像头的 Kivy。我跟随@Arnav this example 使用 opencv 来形成和显示相机作为一个小部件。我有"extended"里面的布局python,添加两个按钮作为测试,为更复杂的布局做准备。
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)
虽然这可行,但我更愿意将 UI 组件移出 python 并移入 kv language
文件。
问题是知道如何 "describe" kv
文件中的 self.my_camera
?
我不确定是否将 KivyCamera
class 作为 kv
文件中的 widget
继承,即
kv = '''
<Cam1@KivyCamera>:
texture: self.my_camera
resolution: (1920, 1080)
pos: self.pos
size: self.size
或者是否使用 canvas
小部件
<MyWidget>:
canvas:
Rectangle:
source: self.my_camera
pos: self.pos
size: self.size
我尝试了其他 "hacked" 实现,但在所有情况下,问题都是通过 self.my_camera
链接到 kv
文件。
有什么建议吗?
也许这个例子可以帮到你。
# 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()
和 kv 文件:
<QrtestHome>:
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()