python - 更新 Kivy 中子对象小部件的位置(Python 不是 .kv)
问题描述
我有一个父小部件,可以添加和定位自定义小部件对象,但是当调整窗口大小时,它们不会更新它们的位置......
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?
解决方案
我看到您正在使创建 _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()
推荐阅读
- tensorflow - Tensorboard for Windows for Tensorflowsharp
- python - 在python中将对象类型初始化为相应的空值
- arrays - 在 PowerShell 中,针对大型数组的批量正则表达式删除速度非常慢
- antlr - Antlr 语法与预期的词法分析器规则不匹配
- docker - docker start 和 docker container start 有什么区别吗?
- excel - 按记录将 Access 查询结果导出到文件中的新工作表
- angular - angular 6 material2 mat-table MatRipple 错误
- android - OkHttp 忽略日志拦截器
- javascript - 方法名(arg) {} ≠ 方法名 = arg =>{}
- batch-file - 为什么我的 if 语句块似乎无法批量到达?