Rounded corners with Kivy (using Python only)

Ferd

I have this little Kivy app (Python version: 3.7, Kivy version: 1.11.1):

Code#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()

And with that code, I have the following result:

enter image description here

Cute, isn't it?

Now, let's try to get the same result using only Python. I'm trying with the following code:

Code#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()

Fair enough, I thought.

But then I got this result:

enter image description here

As far as my knowledge goes, both instructions (Code#1 and Code#2) are saying the same, but in different ways. Scientifically proven, it's not like that.

...So what I'm trying to understand here, and the point of my question, is: what's the functional difference between Code#1 and Code#2? Why are they displaying different results? And what would be the correct way to "translate" Code#1 into Python-only code?

Ignore the fact that just keeping the kivy code is the easiest solution. What I need here is to understand this behaviour, explaining my reasons would unnecessarily extend this question, let's just say you can only control what you understand.

eyllanesc

You have 2 errors:

  • The item is not a Rectangle but a RoundedRectangle.
  • In .kv the canvas is repainted if a property used in the painting changes as there is a binding, however in Python you have to make that binding explicitly.
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()

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Rounded corners on rectangular image using CSS only

Only rounded bottom corners?

Rounded corners for each row of an HTML table using only CSS?

Creating rounded corners using CSS

Drawing Rounded Corners Using UIBezierPath

Rounded Corners only for the bottoms edges of UITableView

Java - Only Two Rounded Corners on a JFrame

NativeScript: WebView with rounded corners (Android Only)

Android - drawable with rounded corners at the top only

Android: how to clip only top rounded corners

ImageView with only bottom or top corners rounded

How to get rounded corners only for topLeft and bottomLeft corners?

Drawing a rectangle with only two rounded corners using Bezier Path and Storyboarding in Swift 2.3

Error when making rounded corners for buttons in Kivy v2.0.0

How to draw a rectangle with rounded corners using XML?

rounded corners on NSView using NSBezierPath are drawn badly

Makes rounded corners on image using PHP GD

Creating a border with rounded corners using SVG masks results in lighter corners

vuetify v-card only two rounded corners

How to create a layout with rounded corners on only the top or bottom half?

individual rounded corners (NOT all corners)

Rounded LineBorder - not all corners are rounded

UIImageView image is stretching when i am using rounded corners.

How to rounded the corners when I draw rectangle using UIBezierPath points

Corners of button not staying rounded when using constraints constraints

Using bezier curves to draw a rectangle with rounded corners in PyMuPDF

How to create Path with rounded corners using rQuadTo that is equivalent to a specific dp?

How to draw text on a rectangle with rounded corners using ffmpeg?

UIAlertController with square (not rounded) corners