I'm writing a program in Kivy, and have run into a roadblock. Camera objects (from kivy.uix.camera
) respond to changes in size_hint
, but do not respond to changes in pos_hint
. For pos_hint, it instead always centers the camera feed in the imaginary box drawn by size_hint (ie if size_hint: (0.5, 0.5)
, then the feed would be centered within the bottom left half of the window, regardless of what pos_hint is set to).
Here is a minimum reproducible example. If you want different size_hint
or pos_hint
values, feel free to alter the values given:
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
I figured it out so I'll share my solution. There were two issues with my code. First, I realized that kivy.uix.camera.Camera
is derived from kivy.uix.image.Image
, so I checked those docs and sure enough, they said:
By default, the image is centered and fits inside the widget bounding box. If you don't want that, you can set allow_stretch to True and keep_ratio to False.
This explains the widget resizing (ie the "imaginary box") but not the actual video feed. The other issue I had was that I was trying to set all the properties under the CameraStream:
of <RootWidget>
, when I actually needed to set them under the Camera:
of <CameraStream>
since it is the Camera object I'm modifying, not the CameraStream FloatLayout that contains it.
Resolving both of these issues made it work how I desired. For completeness, here is my updated lifter.kv file (the main.py file was unchanged):
#: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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.