Search code examples
pythonkivykivy-language

I had a problem with creating a popup in kivy with rounded edges


I tried to create a white popup window with rounded edges as the first image by using a canvas, but when I write canvas.after or canvas.before it comes behind or above the popup window content, so how I can make it looks like the first image?

First image Second image

.py file:

from kivy.app import App 
from kivy.core.window import Window 
from kivy.uix.button import Button 
from kivy.uix.label import Label 
from kivy.uix.widget import Widget 
from kivy.lang import Builder 
from kivy.core.text import LabelBase 
from kivy.uix.popup import Popup



Window.size = [300,600]

    

class MyLayout(Widget):
    pass 



class Exercise(App):

    def build(self):

        #Window color
        Window.clearcolor = (249/255.0, 249/255.0, 249/255.0, 0)

        Builder.load_file("myfile.kv")
        #Loading .kv file 

        
        return MyLayout()




if __name__ == "__main__":

     Exercise().run()

.kv file:

#: import Factory kivy.factory.Factory


<MyPopup@Popup>
    auto_dismiss: False
    title: ""
    separator_height: 0
    size_hint: 0.8, 0.4
    background_color: (0,0,0,0)
    background_normal: ''

    canvas.before:
        Color:
            rgba:(255/255,255/255,255/255,1)

        RoundedRectangle:
            pos: self.pos
            size: self.size
            radius: [40]
        


    BoxLayout:
        orientation: "vertical"
        size: root.width, root.height
        padding: 0, 10, 10, 10
        border: 50
        border_color: (1,1,1,1)

        Label: 
            text: "Good job"
            color: 0,0,0,1
            font_size: 16
            

            
        CloseButton:
            text: "Close"
            color: 0,0,0,1
            size_hint: (None , None)
            width: 105
            height: 40
            pos_hint: {'center_x':0.5}
            on_release: root.dismiss()
            
    

<MyLayout>:
    
    
    BoxLayout:
        orientation: "vertical" 
        size: root.width, root.height
        padding: 20,40
        #spacing: 20


        Label:
            font_size: 20
            text: 'Click the button'
            color: 0, 0, 0, 1        
            


        MyButton:
            font_size: 20
            text: "Button"
            color: (0,0,0,1)
            size_hint: (None , None)
            width: 250
            height: 50
            pos_hint: {'center_x':0.5}
            on_release: Factory.MyPopup().open()
            
                


<CloseButton@Button>:
    background_color: (0,0,0,0)
    background_normal: ''
    canvas.before:
        Color: 
            rgba:(252/255,131/255,87/255,1) 
        RoundedRectangle:
            pos: self.pos
            size: self.size
            radius: [20]



<MyButton@Button>
    background_color: (0,0,0,0)
    background_normal: ''
    canvas.before:
        Color: 
            rgba:(252/255,131/255,87/255,1) 
        RoundedRectangle:
            pos: self.pos
            size: self.size
            radius: [25]

Solution

  • Remove the canvas.before from the first part of the Popup and add it to the BoxLayout. Adjust the size and position of the canvas.before to make it cover the default background.

    Here is the modified Popup definition that will work.

    <MyPopup@Popup>
        auto_dismiss: False
        title: ""
        separator_height: 0
        size_hint: 0.8, 0.4
    
        BoxLayout:
            orientation: "vertical"
            size: root.width, root.height
            padding: 0, 10, 10, 10
            border: 50
            border_color: (1,1,1,1)
            canvas.before:
                Color:
                    rgba: 1, 1, 1, 1
    
                RoundedRectangle:
                    pos: self.x - 20, self.y - 20
                    size: self.width + 40, self.height + 60
                    radius: [40]
            Label:
                text: "Good job"
                color: 0,0,0,1
                font_size: 16
    
    
    
            CloseButton:
                text: "Close"
                color: 0,0,0,1
                size_hint: (None , None)
                width: 105
                height: 40
                pos_hint: {'center_x':0.5}
                on_release: root.dismiss()
    

    enter image description here