NarūnasK
NarūnasK

Reputation: 4950

Placing an image in the middle of the label in Kivy

I have the following Kivy language file, which should mimic a dialer app. Also in the middle underneath the digits it should display an icon (red rectangle). However it seems that in my implementation the parent, self and root objects all have the same properties. What's wrong in my code? Is there a better way to do it?

# File name: dialer.kv 
#:kivy 1.9.0
<Button>:
    color: .8,.9,0,.65
    font_size: 32

<MyGridLayout>:
    rows: 3
    spacing: 10
    GridLayout:
        rows: 1
        size_hint_y: .40
        Label:            
            text: '12345678901231234567890'
            size: self.texture_size
            text_size: root.width, None
            font_size: 44
            halign: 'center'
            valign: 'middle'
            canvas.before:
                Rectangle:
                    pos: self.parent.center_x - self.width / 2, self.parent.center_y - self.height / 2
                    source: 'bg.png'
    GridLayout:
        cols: 3
        rows: 4
        size_hint_y: .50
        spacing: 10
        Button:
            text: '1'
        Button:
            text: '2'
        Button:
            text: '3'
        Button:
            text: '4'
        Button:
            text: '5'
        Button:
            text: '6'
        Button:
            text: '7'
        Button:
            text: '8'
        Button:
            text: '9'
        Button:
            text: '*'
        Button:
            text: '0'
        Button:
            text: '#'
    GridLayout:
        cols: 2
        size_hint_y: .10
        spacing: 10
        Button:
            text: 'Clear'
        Button:
            text: 'Dial'

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# File name: main.py

import kivy
kivy.require('1.9.0')

from kivy.app import App
from kivy.uix.gridlayout import GridLayout

class MyGridLayout(GridLayout):
    pass

class DialerApp(App):
    def build(self):
        return MyGridLayout()

if __name__=="__main__":
    DialerApp().run()

Dialer app

Upvotes: 1

Views: 6739

Answers (1)

Nykakin
Nykakin

Reputation: 8747

self variable you're using inside the canvas instructions is referencing to enclosing widget class (in this case it's a label), not a VertexInstruction like Rectangle. In your code self.parent.center_x is in fact the center of GridLayout and the self.width is the label width. To place your image in the middle of the label you can calculate the position manually:

<MyGridLayout>:
    rows: 3
    spacing: 10
    GridLayout:
        rows: 1
        size_hint_y: .40
        Label:            
            # ...

            canvas.before:
                Rectangle:
                    pos: self.center_x - 50, self.center_y - 50 # default size is 100x100       
                    source: 'test.png' 

    # ...

You can also use Image widget as follows:

<MyGridLayout>:
    rows: 3
    spacing: 10
    GridLayout:
        rows: 1
        size_hint_y: .40
        Label:            
            # ...

            Image:
                center: self.parent.center
                source: 'test.png'               

    # ...

Image is a Widget so now self refers to it and self.parent refers to the Label and we can use the center attribute to calculate the position automatically.

Upvotes: 2

Related Questions