Search code examples
pythonkivykivy-language

how to center canvas? kivy


How to place the white square to the center? I tried a lot of variants, but nothing worked. It work for Label and Buttons, but not for canvas. Or maybe I'm doing everything in wrong way. maybe you suggest the best solution for this task. I need window with background, label in left corner, label in right corner and a square in center

from kivy.app import App
from kivy.uix.widget import Widget

from kivy.uix.floatlayout import FloatLayout
from kivy.config import Config
from kivy.animation import Animation

from kivy.vector import Vector
from kivy.clock import Clock
from kivy.properties import NumericProperty, ReferenceListProperty,\
    ObjectProperty

Config.set('graphics', 'resizable', 'true')
Config.set('graphics', 'width', '900')
Config.set('graphics', 'height', '450')
Config.write()

class Helicopter(Widget):
    pass


class Background(Widget):
    pass


class Root(FloatLayout):
    #def on_touch_down(self, touch):
     #   Animation(center=touch.pos).start(self)
    pass

class FriendsApp(App):
    def build(self):

        return Root()

if __name__ == '__main__':
    FriendsApp().run()

.kv file

#: kivy 1.10.0
<Root>
    AnchorLayout:
        canvas.before:
            Color:
                rgba: 1, 1, 1, 1  # white
            Rectangle:
                source: 'background.jpg'
                pos: self.pos
                size: self.size
        size: self.parent.size
        anchor_x: 'center'
        anchor_y: 'center'


    AnchorLayout:
        anchor_y:'top'
        anchor_x:'left'
        padding: 20
        Label:
            text: 'Lives: x2'
            size: self.texture_size
            size_hint: None, None

    AnchorLayout:
        anchor_x: 'right'
        anchor_y: 'top'
        padding: 20
        Label:
            text: 'Score: 0000000'
            size: self.texture_size
            size_hint: None,None

    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'center'
        canvas:
            Rectangle:
                size: 100, 100
                pos: self.pos

Solution

  • The AnchorLayout has its own canvas and you cannot aligns itself. There are two solutions to this problem. In the example, colors were added for visualization.

    The AnchorLayout aligns its children to a border (top, bottom, left, right) or center.

    Solution 1

    Add a Widget as a children.

    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'center'
        Widget:
            canvas.before:
                Color:
                    rgba: 1, 1, 1, 1  # white
                Rectangle:
                    size: 100, 100
                    pos: self.pos
            size_hint: None,None
    

    Solution 2

    Replace the last AnchorLaoyout with Widget.

    Widget:
        canvas:
            Rectangle:
                pos: self.center_x - 50, self.center_y - 50
                size: 100, 100
    

    Example - Solution 1

    kv file

    #: kivy 1.10.0
    
    <Root>
        AnchorLayout:
            anchor_y:'top'
            anchor_x:'left'
            padding: 20
            Label:
                canvas.before:
                    Color:
                        rgba: 1, 0, 0, 1  # red
                    Rectangle:
                        pos: self.pos
                        size: self.size
                text: 'Lives: x2'
                size: self.texture_size
                size_hint: None, None
    
        AnchorLayout:
            anchor_x: 'right'
            anchor_y: 'top'
            padding: 20
            Label:
                canvas.before:
                    Color:
                        rgba: 0, 0, 1, 1  # blue
                    Rectangle:
                        pos: self.pos
                        size: self.size
                text: 'Score: 0000000'
                size: self.texture_size
                size_hint: None,None
    
        AnchorLayout:
            anchor_x: 'center'
            anchor_y: 'center'
            Widget:
                canvas.before:
                    Color:
                        rgba: 1, 1, 1, 1  # white
                    Rectangle:
                        size: 100, 100
                        pos: self.pos
                size_hint: None,None
    

    Output

    Img01