简体   繁体   中英

Why isn't this rectangle centered in Kivy?

I'm trying to draw a rectangle in the center of my widget:

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


class MyWidget(Widget):
    def __init__(self):
        super(MyWidget, self).__init__()
        with self.canvas:
            Rectangle(pos=(self.center_x, self.center_y)


class MyApp(App):
    def build(self):
        return MyWidget()


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

This is what I'm getting:

确实是形象

Doing the exact same thing using a .kv file works:

<MyWidget>:
    canvas:
        Rectangle:
            pos: self.center_x, self.center_y

Please explain how to achieve what I'm trying to do, and why it does work using a .kv file, as opposed to Python code. Thank you

If you add the Widget from a kv file the the widget will be automatically be attached to the App's root attribute and used as the base of the application widget tree. So in your situation from the kv file the size of the widget is automatically bind to the application windows size and becomes root widget. Taking that into consideration the self.center_x and self.center_y works. You can read this at https://kivy.org/docs/guide/lang.html under the line `MyApp -> my.kv.

When not using a kv file this will not happen and the default size of the widget will be (100,100). To properly place your rectangle use a layout so you can refer use the size_hint to properly place or re size any child widget. As stated in the documentation

FloatLayout honors the pos_hint and the size_hint properties of its children.

https://kivy.org/docs/api-kivy.uix.floatlayout.html#kivy.uix.floatlayout.FloatLayout

So create a Float layout in example, add a widget with pos_hint equals to center_x and center_y that will refer to the layout being a parent and then draw a rectangle to the widget.

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import Rectangle
from kivy.core.window import Window

class myLayout(FloatLayout):
    def __init__(self):
        super(myLayout, self).__init__()
        self.size = Window.size
        self.myWidget = Widget(size=(100,100))
        self.add_widget(self.myWidget)
        with self.myWidget.canvas:
            Rectangle(pos=(self.center_x, self.center_y))


class MyApp(App):
    def build(self):
        return myLayout()


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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM