Kivy: камера не учитывает pos_hint (но учитывает size_hint)

Я пишу программу в Kivy и столкнулся с препятствием. Объекты камеры (из kivy.uix.camera) реагируют на изменения в size_hint, но не реагируют на изменения в pos_hint. Для pos_hint вместо этого он всегда центрирует канал камеры в воображаемой рамке, нарисованной size_hint (т. е. если size_hint: (0.5, 0.5), то канал будет центрироваться в нижней левой половине окна, независимо от того, какое значение установлено для pos_hint).

Вот минимально воспроизводимый пример. Если вам нужны другие значения size_hint или pos_hint, не стесняйтесь изменять указанные значения:

main.py

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
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
209
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я понял это, поэтому я поделюсь своим решением. Было две проблемы с моим кодом. Во-первых, я понял, что 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 

Другие вопросы по теме