我有一个父窗口小部件,用于添加和定位自定义窗口小部件对象,但是当调整窗口大小时,它们不会更新其位置...
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()
结果:
问题是调整窗口大小时会发生这种情况:
如何在python中重新定位childWidgets?
答案 0 :(得分:1)
我看到您正在复杂地创建_pos或_size之类的新属性,相反,您应该仅使用现有属性pos和size,另一方面,您随时都在使用画布,而不是重新使用元素。
考虑到上述情况,简单的解决方案是:
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()