Я пишу программу в Kivy и столкнулся с препятствием. Объекты камеры (из kivy.uix.camera
) реагируют на изменения в size_hint
, но не реагируют на изменения в pos_hint
. Для pos_hint вместо этого он всегда центрирует канал камеры в воображаемой рамке, нарисованной size_hint (т. е. если size_hint: (0.5, 0.5)
, то канал будет центрироваться в нижней левой половине окна, независимо от того, какое значение установлено для pos_hint).
Вот минимально воспроизводимый пример. Если вам нужны другие значения size_hint
или pos_hint
, не стесняйтесь изменять указанные значения:
import kivy
kivy.require('1.11.1')
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.camera import Camera
from kivy.core.window import Window
Window.fullscreen = 'auto' # uses display's current resolution
class CameraStream(FloatLayout):
pass
class RootWidget(FloatLayout):
camera_stream = ObjectProperty(None)
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
class LifterApp(App):
def build(self):
self.root = RootWidget()
return self.root
if __name__ == '__main__':
LifterApp().run()
#:kivy 1.11.1
<CameraStream>:
camera_stream: camera_stream_id
Camera:
id: camera_stream_id
resolution: (320, 240)
play: True
<RootWidget>:
camera_stream: camera_stream_id
CameraStream:
id: camera_stream_id
size_hint: (0.5, 0.5) # this does work
#size_hint: (0.1, 0.1) # ...so does this
#size_hint: (1, 1) # ...and this
pos_hint: {'center_x': 0.1, 'center_y': 0.1} # NOTE this doesn't work
#pos_hint: {'center_x': 0.9, 'center_y': 0.9} # ...neither does this
#pos_hint: {'x': 0, 'y': 0} # ...or this
Я понял это, поэтому я поделюсь своим решением. Было две проблемы с моим кодом. Во-первых, я понял, что kivy.uix.camera.Camera
происходит от kivy.uix.image.Image
, поэтому я проверил эти документы и, конечно же, они сказали:
По умолчанию изображение располагается по центру и помещается внутри ограничивающей рамки виджета. Если вы этого не хотите, вы можете установить для параметра allow_stretch значение True, а для параметра keep_ratio — значение False.
Это объясняет изменение размера виджета (т. е. «воображаемого прямоугольника»), но не сам видеопоток. Другая проблема, с которой я столкнулся, заключалась в том, что я пытался установить все свойства под CameraStream:
из <RootWidget>
, когда мне действительно нужно было установить их под Camera:
из <CameraStream>
, поскольку я изменяю объект камеры, а не CameraStream FloatLayout, который содержит это.
Решение обеих этих проблем заставило его работать так, как я хотел. Для полноты картины вот мой обновленный файл lifter.kv (файл main.py не изменился):
#:kivy 1.11.1
<CameraStream>:
camera_stream: camera_stream_id
Camera:
id: camera_stream_id
resolution: (320, 240)
play: True
allow_stretch: True
keep_ratio: False
size_hint: (0.5, 0.5)
#size_hint: (0.1, 0.1)
#size_hint: (1, 1)
pos_hint: {'center_x': 0.1, 'center_y': 0.1}
#pos_hint: {'center_x': 0.9, 'center_y': 0.9}
#pos_hint: {'x': 0, 'y': 0}
<RootWidget>:
camera_stream: camera_stream_id
CameraStream:
id: camera_stream_id