Закругленные углы с Kivy (только с использованием Python) - PullRequest
1 голос
/ 15 октября 2019

У меня есть это маленькое приложение Kivy (Python версия: 3.7, Kivy версия: 1.11.1):

Код # 1

from kivy.app import App
from kivy.lang import Builder
from kivy.config import Config
from kivy.uix.floatlayout import FloatLayout

Config.set("graphics", "width", "500")
Config.set("graphics", "height", "300")

kv = """
<RoundedCornerLayout@FloatLayout>:
    background_color: 0,0,0,0
    canvas.before:
        Color:
            rgba: (.4,.4,.4,1)
        RoundedRectangle:
            pos: self.pos
            size: self.size
            radius: [(40, 40), (40, 40), (20, 20), (20, 20)]
"""

Builder.load_string(kv)


class RoundedCornerLayout(FloatLayout):
    def __init__(self):
        super().__init__()
        self.size_hint = (None, None)
        self.size = (400, 200)
        self.pos_hint = {"center_x": 0.5, "center_y": 0.5}


class MainApp(App):
    def build(self):
        return RoundedCornerLayout()


if __name__ == "__main__":
    MainApp().run()

И с этимкод, у меня есть следующий результат:

enter image description here

Милый, не правда ли?

Теперь давайте попробуем получить то же самоерезультат использования только Python. Я пытаюсь с помощью следующего кода:

Код # 2

from kivy.app import App
from kivy.config import Config
from kivy.graphics import Color
from kivy.graphics import Rectangle
from kivy.uix.floatlayout import FloatLayout

Config.set("graphics", "width", "500")
Config.set("graphics", "height", "300")


class RoundedCornerLayout(FloatLayout):
    def __init__(self):
        super().__init__()
        self.size_hint = (None, None)
        self.size = (400, 200)
        self.pos_hint = {"center_x": 0.5, "center_y": 0.5}

        self.background_color = (0, 0, 0, 0)
        self.canvas.before.add(Color(.4, .4, .4, 1))
        self.canvas.before.add(Rectangle(
            pos=self.pos,
            size=self.size,
            radius=[(40, 40), (40, 40), (20, 20), (20, 20)]))


class MainApp(App):
    def build(self):
        return RoundedCornerLayout()


if __name__ == "__main__":
    MainApp().run()

Достаточно справедливо, подумал я.

Но потом я получил эторезультат:

enter image description here

Насколько мне известно, обе инструкции (код № 1 и код № 2) говорят одно и то же, но по-разному,Научно доказано, что это не так.

... Итак, что я пытаюсь понять здесь, и смысл моего вопроса заключается в следующем: в чем функциональная разница между Кодом 1 и Кодом 2? Почему они показывают разные результаты? И какой будет правильный способ «перевести» код № 1 в код только на Python?

Не обращайте внимания на тот факт, что просто сохранить код kivy - самое простое решение. Здесь мне нужно понять это поведение, объяснение моих причин излишне расширит этот вопрос, скажем так, вы можете контролировать только то, что понимаете.

1 Ответ

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

У вас есть 2 ошибки:

  • Элемент не прямоугольник, а прямоугольник с закругленными углами.
  • В .kv холст перекрашивается, если свойство, используемое в картине, изменяется по мере измененияэто привязка, однако в Python вы должны сделать эту привязку явно.
from kivy.app import App
from kivy.config import Config
from kivy.graphics import Color, RoundedRectangle
from kivy.uix.floatlayout import FloatLayout

Config.set("graphics", "width", "500")
Config.set("graphics", "height", "300")


class RoundedCornerLayout(FloatLayout):
    def __init__(self):
        super().__init__()

        with self.canvas.before:
            Color(0.4, 0.4, 0.4, 1)
            self.rect = RoundedRectangle(
                pos=self.pos,
                size=self.size,
                radius=[(40, 40), (40, 40), (20, 20), (20, 20)],
            )
        self.bind(pos=lambda obj, pos: setattr(self.rect, "pos", pos))
        self.bind(size=lambda obj, size: setattr(self.rect, "size", size))

        self.size_hint = (None, None)
        self.size = (400, 200)
        self.pos_hint = {"center_x": 0.5, "center_y": 0.5}
        self.background_color = 0, 0, 0, 1


class MainApp(App):
    def build(self):
        return RoundedCornerLayout()


if __name__ == "__main__":
    MainApp().run()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...