Центр холста в Python против кивийского языка - PullRequest
1 голос
/ 23 октября 2019

Я сделал простое приложение, в котором я пытаюсь показать свою проблему. При использовании python для рисования линии в kivy (используя метод с self.canvas) линия рисуется из center_x и center_y, равного 50.

При использовании kivy Lang правильно рисует линию в центре. Вот простой пример кода:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Line


class TestWidget(Widget):

    def draw(self):
        with self.canvas:
            Line(points=[self.center_x,self.center_y,self.center_x,self.center_y+100], width=2)


class TestApp(App):

    def build(self):
        test = TestWidget()
        test.draw()
        return test


if __name__ == '__main__':
    TestApp().run()

и соответствующий файл test.kv:

#:kivy 1.11.1

<TestWidget>:
    canvas:      
        Line:
            width: 5
            points: (self.center_x,self.center_y,self.center_x,self.center_y+100)

результат выглядит так:

enter image description here

Есть идеи, почему использование кода Python не работает?

Ответы [ 2 ]

1 голос
/ 23 октября 2019

Оба кода не эквивалентны, в случае с python вы только устанавливаете, что позиция линии основана на центре виджета в то время, то есть в начале, а не в .kv, это указываетчто позиция линии всегда будет относительно центра виджета.

TL;DR;

Объяснение:

В kv привязка является естественным и неявным процессом, который в python не делает, кроме того, что его реализация проще, например, следующий код:

Foo:
    property_i: other_object.property_j

В этом случае его эквивалент в python:

foo = ...
other_object = ...
other_object.bind(property_j=foo.setter("property_i"))

И это не так:

foo.property_i = other_object.property_j

Поскольку с привязкой вы указываете перед изменением property_j обновить property_i этим значением, но в последнем коде, который вы указали только в этот момент, скопируйте значение property_j в property_i.

В вашем конкретном случае центр, который вы выбираете, находится передотображая виджет и киви, принимая во внимание конфигурации по умолчанию и другие свойства, изменяет геометрию виджета после его отображения.

Решение

Внесение необходимых изменений с учетом предыдущего объяснения следующеекод является эквивалентом кода .kv

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Line


class TestWidget(Widget):
    def __init__(self, **kwargs):
        super(TestWidget, self).__init__(**kwargs)
        with self.canvas:
            self.line = Line(width=2)
        self.bind(center=lambda *args: self.draw())

    def draw(self):
        self.line.points = [
            self.center_x,
            self.center_y,
            self.center_x,
            self.center_y + 100,
        ]


class TestApp(App):
    def build(self):
        test = TestWidget()
        return test


if __name__ == "__main__":
    TestApp().run()
1 голос
/ 23 октября 2019

При использовании языка kv ваши объявления автоматически обновляются при изменении их зависимостей. Это означает, что когда центр виджета переходит от (50, 50) к чему-то другому, линия перерисовывается в новом месте.

Ваш код Python не делает этого, он просто рисует линию один раз, используя любыеего центр в данный момент работает. Это значение (50, 50), так как это значение по умолчанию до того, как произошло позиционирование.

Решение состоит в том, чтобы написать код на Python, который обновляет строку при изменении центра виджета, что-то вроде объявлениястрока с self.line = Line(...) и self.bind(centre=some_function_that_updates_self_dot_line).

...