pythonkivy

Python Kivy canvas alignment off center


Working on a project, and when I programmatically build a grid layout using prebuilt objects and applying a canvas for a background image, for some reason the image is off center (see image below). I've included the relevant code:

Here is the .py code

    card1 = Factory.CardGL()
    with card1.canvas:
        RoundedRectangle(source=GS_IMG_LSRC, size = card1.size, pos = card1.pos)
    sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids.DB_MAIN_BL_T_01.add_widget(card1)
    sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids['card_1'] = weakref.ref(card1)
    cardtopgl = Factory.CardTopGL()
    sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids.card_1.add_widget(cardtopgl)
    sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids['cardtop_gl'] = weakref.ref(cardtopgl)
    cardtopbt = Factory.CardTopBT(text = '[b]Grocery[/b]')
    sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids.cardtop_gl.add_widget(cardtopbt)
    sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids['cardtop_bt'] = weakref.ref(cardtopbt)

Here is the relevant prebuilt objects from my .kv file:

<CardGL@GridLayout>:
    background_color: 1,1,1,0
    canvas.before:
        Color:
            rgb: kivy.utils.get_color_from_hex('#000000')
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [10,10,10,10]
        BoxShadow:
            pos: self.pos
            size: self.size
            offset: 5, -5
            spread_radius: -7, -7
            border_radius: [10,10,10,10]
            blur_radius: 10
    canvas:
        Color:
            rgb: 1,1,1,0
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [10,10,10,10]
    cols: 1
    size: dp(Factory.WinCalcs.LB_LTW * .36), dp(Factory.WinCalcs.GL_LTH_C * .6)
    size_hint: None, None
    padding: dp(0),dp(0)

And here is the outcome, the background should be aligned with the header:

Weirdly Unaligned

Would really appreciate some guidance, kivy is relatively new to me.


Solution

  • Ok, so, the answer I used looked like this:

    class MyClassName(App):
        def __init__(self, **kwargs):
            super(MyClassName, self).__init__(**kwargs)
            Clock.schedule_once(lambda dt: self.place_canvas(), timeout=0.01)
        #Create card
        card1 = Factory.CardGL()
    
        #Placing card in scrolling layout
        sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids.DB_MAIN_BL_T_01.add_widget(card1)
        sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids['card_1'] = weakref.ref(card1)
    
    
    
    
        def place_canvas(self):
            self.core_item = sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN')
            self.bound_item = self.core_item.ids.card_1
            self.size_out = StringProperty()
            self.pos_out = StringProperty()
            self.size_out = self.bound_item.size
            self.pos_out = self.bound_item.pos
            self.bound_item.canvas.add(RoundedRectangle(source = self.GS_IMG_LSRC, pos = self.pos_out, size = self.size_out))
            # Header
            cardtopgl = Factory.CardTopGL()
            self.core_item.ids.card_1.add_widget(cardtopgl)
            self.core_item.ids['cardtop_gl'] = weakref.ref(cardtopgl)
            cardtopbt = Factory.CardTopBT(text='[b]Grocery[/b]')
            self.core_item.ids.cardtop_gl.add_widget(cardtopbt)
    
    
    
    

    I didn't need to change any of the .kv stuff, and I've eliminated some of the other things I put in the card for berevities sake, but this should give a picture of what solved my issue. Basically I just made python wait until the object was rendered and placed before putting anything in it. This probably isn't the most ideal solution, but it works for my needs atm.

    Thanks to the people who commented, even though I didn't use your exact solution, it took me down the road to find what I needed.