Reputation: 3955
I have a parent widget that adds and positions custom widget objects, but when the window is resized they don't update their position...
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Color, Line, Ellipse, Rectangle
from kivy.metrics import dp
from kivy.uix.widget import Widget
class circleChild(Widget):
def __init__(self, *args, **kwargs):
self.pos = kwargs.get('_pos')
self.size = kwargs.get('_size')
super(circleChild, self).__init__()
with self.canvas:
Color(0.4, 0.6, 0.9, 1) # ConrflowerBlue
Ellipse(pos=self.pos, size=self.size, width=dp(2))
class RootWidget(BoxLayout):
def __init__(self, *args, **kwargs):
BoxLayout.__init__(self, *args, **kwargs)
self.bind(pos=self.draw)
self.bind(size=self.draw)
self.layout1 = BoxLayout()
self.layout2 = BoxLayout(opacity=0.8)
self.add_widget(self.layout1)
self.add_widget(self.layout2)
self.childrenAdded = False
def draw(self, *args):
with self.canvas.before:
Color(.8, .8, .8, 1) # LightGrey
self.bg = Rectangle(pos=self.pos, size=self.size)
self.layout1.canvas.clear()
with self.layout1.canvas:
Color(0, 0, 0, 1) # Black
Line(
points=[
self.center_x, self.center_y - 200, self.center_x,
self.center_y + 200
],
width=dp(2))
Line(
points=[
self.center_x - 200, self.center_y, self.center_x + 200,
self.center_y
],
width=dp(2))
if not self.childrenAdded:
self.addChildren()
def addChildren(self, *args):
circle1 = circleChild(
_pos=[self.center_x + 100, self.center_y + 100], _size=[100, 100])
circle2 = circleChild(
_pos=[self.center_x + 100, self.center_y - 200], _size=[100, 100])
circle3 = circleChild(
_pos=[self.center_x - 200, self.center_y + 100], _size=[100, 100])
circle4 = circleChild(
_pos=[self.center_x - 200, self.center_y - 200], _size=[100, 100])
self.layout2.add_widget(circle1)
self.layout2.add_widget(circle2)
self.layout2.add_widget(circle3)
self.layout2.add_widget(circle4)
self.childrenAdded = True
class PositionChildren(App):
title = "PositionChildren"
def build(self):
return RootWidget()
if __name__ == "__main__":
PositionChildren().run()
Results in:
The problem is when resizing the window, this happens :
How would reposition the childWidgets in python?
Upvotes: 2
Views: 871
Reputation: 244301
I see that you are complicating creating new properties like _pos or _size, instead you should only use the existing properties pos and size, on the other hand you are using the canvas at every moment, instead reusing the elements.
Considering the above, the simple solution is:
from kivy.app import App
from kivy.graphics import Color, Line, Ellipse, Rectangle
from kivy.metrics import dp
from kivy.uix.widget import Widget
class circleChild(Widget):
def __init__(self, **kwargs):
super(circleChild, self).__init__(**kwargs)
self.draw()
self.bind(pos=self.redraw, size=self.redraw)
def draw(self):
with self.canvas:
Color(0.4, 0.6, 0.9, 1) # ConrflowerBlue
self.ellipse = Ellipse(width=dp(2))
def redraw(self, *args):
# reuse
self.ellipse.pos = self.pos
self.ellipse.size = self.size
class RootWidget(Widget):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
self.draw()
self.bind(pos=self.redraw, size=self.redraw)
self.circle1 = circleChild(size=[100, 100])
self.circle2 = circleChild(size=[100, 100])
self.circle3 = circleChild(size=[100, 100])
self.circle4 = circleChild(size=[100, 100])
for c in (self.circle1, self.circle2, self.circle3, self.circle4):
self.add_widget(c)
def draw(self):
with self.canvas.before:
Color(.8, .8, .8, 1) # LightGrey
self.bg = Rectangle(pos=self.pos, size=self.size)
Color(0, 0, 0, 1) # Black
self.vline = Line(width=dp(2))
self.hline = Line(width=dp(2))
def redraw(self, *args):
# reuse
self.bg.pos = self.pos
self.bg.size = self.size
self.vline.points = [
self.center_x,
self.center_y - 200,
self.center_x,
self.center_y + 200
]
self.hline.points=[
self.center_x - 200,
self.center_y,
self.center_x + 200,
self.center_y
]
self.circle1.pos = [self.center_x + 100, self.center_y + 100]
self.circle2.pos = [self.center_x + 100, self.center_y - 200]
self.circle3.pos = [self.center_x - 200, self.center_y + 100]
self.circle4.pos = [self.center_x - 200, self.center_y - 200]
class PositionChildren(App):
title = "PositionChildren"
def build(self):
return RootWidget(size=(100, 100))
if __name__ == "__main__":
PositionChildren().run()
Upvotes: 1