1

I am trying to construct a widget in the middle of the screen. I am not using pos_hint or size_hint because I will be altering the widget's position later but when I construct the widget, its size and position is not correct. Here is my code:

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.graphics import *
from kivy.clock import Clock


class Sprite(Widget):

    def __init__(self, **kwargs):
        super(Sprite, self).__init__(**kwargs)
        Clock.schedule_interval(self.update_canvas, 1.0/60)

    def update_canvas(self, dt):
        with self.canvas:
            Rectangle(size=self.size, pos=self.pos)


class RootWidget(FloatLayout):
    def __init__(self, **kwargs):
        super(RootWidget, self).__init__(**kwargs)
        self.add_widget(Sprite(
            size=(Window.width*0.1, Window.height*0.1),
            center=(Window.width*0.5, Window.height*0.5)
        ))


class MyApp(App):
    def build(self):
        app = RootWidget()
        return app

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

Why is the widget's size not equal to 1/10th of the window size and why is it's center at the top right corner of the window?

3
  • because size_hint and pos_hint bind the attributes to the widget. I then can't alter the position of the widget by simply increasing or decreasing its x and y values. With the code above add "self.x+=1" to the update canvas function and the widget will move. If I tried that with pos_hint defined then the widget's position resets every frame back to its original position. Commented Nov 8, 2014 at 20:36
  • Are you sure the floatlayout is automatically filling the entire window size? If it wasn't, it might explain why Sprite isn't doing what you want. Perhaps try setting the size of RootWidget to it's parent size(maybe window.size) first and then setting Sprites size and center may work. Commented Nov 8, 2014 at 21:15
  • Yes RootWidget is the root widget as defined when returned in MyApp's build function. It automatically takes shape of the window and re-sizes itself if the window changes size. I added a function to RootWidget to print out its size as well as the size of the Window and they are identical. Commented Nov 8, 2014 at 21:38

1 Answer 1

3

The size hint defaults to a value unless you define it explicitly and it takes priority over the size property. You may not want to want to use the size hint functionality but unless you disable it, the size that you set manually will be overridden by default. Try adding the following modification and compare the result with and without the size_hint line:

    self.add_widget(Sprite(
        size_hint=(None,None),
        size=(Window.width*0.1, Window.height*0.1),
        center=(Window.width*0.3, Window.height*0.5)
    ))

You can see the actual dimensions set by using the inspector: python myscript.py -m inspector and hitting control+E in the kivy window

reference: http://kivy.org/docs/api-kivy.modules.inspector.html

center is an alias for (x + width/.2, y + height/.2) but the width and height default to 100. At the time of creation these default measurements are what are used for the reverse calculation to set x and y when you make your call so if your height and width are different from 100 then you'll be offset by the difference. Use x and y directly (i.e. pos=(..)) when instantiating, not center.

Sign up to request clarification or add additional context in comments.

4 Comments

but the center position is not centered if I use "center=(Window.width*0.5,Window.height*0.5)." I measured the distance from the top of the widget to the top of the window and the bottom of the widget to the bottom of the window where I am reading different measurements. Also with the left and right side of the window in relation with the left and right side of the widget is also not equal.
you're correct. I hadn't noticed the offset. I updated my answer
thank you. I changed center to "pos=(Window.width*0.5-Window.width*0.05, Window.height*0.5-Window.height*0.05)" and printed the widgets center and the Window's center and they are identical now.
There's a secondary issue with binding that's addressed by inclem.net's blog: inclem.net/2014/10/10/kivy/kivy_update_instructions I expect this is probably also relevant to your problem and you may need to do something similar if you expect the pos/size to update automatically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.