Is it possible to set the radius value in a ScrollView in Python/Kivy?

Question:

I need a rounded scrollview that rounds along with the children, I did a lot of research on this but failed, I didn’t find anything about it.

Something like:

ScrollView:
    do_scroll: [False, True]
    radius: [dp(30),]
    MDList:
        id: list

This does not round the scrollview. Any idea how I can do thiswithout adding the RoundedRectangle chart?

Edit:

Adding the RoundedRectangle graph looks good, but it doesn’t solve my problem. It is as if the children of the ScrollView exceeds the radius, the children do not fit in the radius.

ScrollView Code:

<RoundedScrollView@ScrollView>:
    canvas.before:
        Color:
            rgba: 1, 0, 0, 1
        RoundedRectangle:
            pos: self.pos
            size: self.size
            radius: [0, 0, dp(80), 0]

Where I used ScrollView:

Screen:
    RoundedSrollView:
        MDList:
            id: list
            radius: [0, 0, dp(80), 0] #does not work

Result:

enter image description here

Asked By: Hugo Cezar

||

Answers:

You can do something like this in your kv:

<RoundedScrollView@ScrollView>:
    radius: 0
    canvas.before:
        Color:
            rgba: 1, 0, 0, 1
        RoundedRectangle:
            pos: self.pos
            size: self.size
            radius: [self.radius]

This draws a red rounded rectangle as the background of a RoundedScrollView. You can add more Properties to the RoundedScrollView to control, for example, the color.

Answered By: John Anderson

Well… After a long time (literally) I found a solution to define a radius to a ScrollView that automatically cuts the child. The solution is to redraw the ScrollView clipping using the canvas instructions StencilPush , StencilUse , StencilUnUse and StencilPop.

main.py

from kivymd.app import MDApp
from kivy.lang import Builder

KV = """
MDScreen:
    MDScrollView:
        do_scroll: [False, True]
        size_hint: .5, .5
        pos_hint: {"center":[.5, .5]}

        canvas.before:
            StencilPush
            RoundedRectangle:
                pos: self.pos
                size: self.size
                radius: [dp(50),]
            StencilUse

        canvas.after:
            StencilUnUse
            StencilPop

        MDBoxLayout:
            adaptive_height: True
            size_hint_y: None

            MDLabel:
                text:
                    'The ScrollView accepts only one child and applies a viewport' 
                    '/window to it according to the scroll_x and scroll_y properties.' 
                    ' Touches are analyzed to determine if the user wants to scroll or' 
                    ' control the child in some other manner: you cannot do both at the' 
                    ' same time. To determine if interaction is a scrolling gesture,' 
                    ' these properties are used:'
                adaptive_height: True
"""

class MyApp(MDApp):
    def build(self):
        return Builder.load_string(KV)

MyApp().run()

StencilPush is being used to save the current state of the Stencil and below it a rounded rectangle with the same dimensions and size as the ScrollView is being drawn.

StencilUse defines that this rounded rectangle will be the current Stencil.

After all the modifications have been made it is necessary to clean the "old" Stencil and set the modified Stencil as the default that was made under StencilPush. This is done using the StencilUnUse instruction and then the finalization, StencilPop, it is not mandatory but this ensures that all states are cleared and that performance is not affected.

Answered By: Hugo Cezar
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.