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 Answer
Reset to default 0Ok, 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.
kv
, bindings are setup for you automatically. So, for example, thesize: self.size
for yourRoundedRectangle
sets up a binding that will adjust the size of theRoundedRectangle
whenever thesize
of theCardGL
changes. However, when you usesize = card1.size
in python, thesize
of theRoundedRectangle
is set to the size ofcard1
at the instant that the python code is executed (which could even be the default widgetsize
of 100,100) and no binding is created, so that size will not adjust to any changes in thesize
ofcard1
. – John Anderson Commented Mar 5 at 17:43size
andpos
of the parent widget areProperties
. – John Anderson Commented Mar 5 at 21:42