1
votes

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?

1
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.Richard Morales
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.Totem
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.Richard Morales

1 Answers

3
votes

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.