Pregunta

Problem in hand is that i have a screen where i have created 4 widgets under gridlayout . Widget one is a custom widget which have a boxlayout and have 2 images and a button . and other 3 widgets are simple buttons Now i want to have a background image or coloured rectangle to the 1st widget but image is getting drawn at position 0,0 . I am trying to use canvas instructions to create a rectangle or Border Image but seems gridlayout shows the widget position as 0,0 and hence it created the rectangle at 0,0 . please see the code below :

Any ideas how to fix this and create rectangle as at the border of widget 1?

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen,FallOutTransition
from kivy.uix.image import Image
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.graphics import BorderImage
from kivy.graphics import Color, Rectangle ,Line

#################     Images   ######################
S = Image(source='images/Sti.png')
L = 'images/spinnin.gif'
#################     Images   ######################

class CButtonW(BoxLayout):
    def __init__(self, **kwargs):
        print "init --> CButton self.pos is ",self.pos
        super(CButtonW, self).__init__(**kwargs)
        self.orientation = 'vertical'
        with self.canvas.before:
            Color(1, 1, 0, 1, mode='rgba')
            Rectangle(pos=self.pos,size=self.size)
            BorderImage(
                     border=(10, 10, 10, 10),
                    source='images/tex.png')

        self.add_widget(S)
        self.add_widget(Button(text="Button 1"))
        self.add_widget(Image(source=L))


class LevelScreen(Screen,GridLayout):
    def __init__(self, **kwargs):
        super(LevelScreen, self).__init__(**kwargs)
        with self.canvas:
            Line(points=(10, 10, 20, 30, 40, 50))
            Color(1, 0, 1, 1, mode='rgba')
            Rectangle(pos=self.pos, size=Window.size)

        self.layout = GridLayout(cols=3,spacing=1,padding=10)
        self.Button1 = CButtonW(id='1',text='Level 1')
        self.Button2 = Button(id='2',text='Level 2')
        self.Button3 = Button(id='3',text='Level 3')
        self.Button4 = Button(id='4',text='Level 4')
        self.layout.add_widget(self.Button1)
        self.layout.add_widget(self.Button2)
        self.layout.add_widget(self.Button3)
        self.layout.add_widget(self.Button4)

        LevelScreen.cols=3
        LevelScreen.add_widget(self,self.layout)
        print "position of 1st button is ",self.Button1.pos
        print "position of 2 button is ",self.Button2.pos

# App Class
class MyJBApp(App):
    def build(self):
        sm = ScreenManager(transition= FallOutTransition())
        sm.add_widget(LevelScreen(name='level'))
        return sm

if __name__ == '__main__':
    MyJBApp().run()
¿Fue útil?

Solución

Your canvas instructions are drawn before the CButtonW is positioned by its layout, so at that point it's still in its default position of 0, 0.

You can fix it by adding code to reposition the instructions when the widget's position or size changes. The easiest way is to just use kv language in the first place, which will automatically create the relevant bindings, but you can also bind to pos or size in python, or use the on_propertyname events associated with their changes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top