最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Python Kivy canvas alignment off center - Stack Overflow

programmeradmin1浏览0评论

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.

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.

Share asked Mar 5 at 16:57 Manic LyndonManic Lyndon 13 bronze badges 3
  • 1 When you use kv, bindings are setup for you automatically. So, for example, the size: self.size for your RoundedRectangle sets up a binding that will adjust the size of the RoundedRectangle whenever the size of the CardGL changes. However, when you use size = card1.size in python, the size of the RoundedRectangle is set to the size of card1 at the instant that the python code is executed (which could even be the default widget size of 100,100) and no binding is created, so that size will not adjust to any changes in the size of card1. – John Anderson Commented Mar 5 at 17:43
  • So can I bind the size and pos so that it adjusts with the parent object? – Manic Lyndon Commented Mar 5 at 17:47
  • Yes, See the documentation. The size and pos of the parent widget are Properties. – John Anderson Commented Mar 5 at 21:42
Add a comment  | 

1 Answer 1

Reset to default 0

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.

发布评论

评论列表(0)

  1. 暂无评论