kivy小部件总是更新到父小部件的大小



使用kivy,我试图创建自己的下拉菜单,以解决内置dropdown小部件的一些问题。但是,当调整小部件的大小以设置打开序列的动画时,小部件的尺寸保持不变。经过进一步的调查,我意识到小部件的大小总是与父RelativeLayout相同,但我找不到原因。这是一个最低工作代码

from kivy.animation import Animation
from kivy.clock import Clock
from kivy.uix.relativelayout import RelativeLayout
from kivy.lang import Builder
import kivy.properties as props

KV = '''
#:import MaterialWidget materialwidget.MaterialWidget
<DropDown@RelativeLayout>
_background: background
canvas:
Color:
rgba: 1, 0, 0, 1
Rectangle:
pos: root._pos
size: root._size
Button:
id: background
size: root._size
pos: root._pos
on_size: print("size_changed", self.size)
'''
class DropDown(RelativeLayout):
opened = props.BooleanProperty(False)
anchor = props.OptionProperty("tl", options=["tr", "tl", "br", "bl"])
_size = props.ListProperty([0, 0])
_pos = props.ListProperty([0, 0])
_background = props.ObjectProperty(None)
def __init__(self, **kwargs):
super(DropDown, self).__init__(**kwargs)
#self.add_widget(self._background)
trigger = Clock.create_trigger(lambda *args: self.on_pos())
trig = Clock.create_trigger(lambda *args: self.on_size())
self.bind(
anchor=trigger,
_size=trigger,
opened=trig
)
def on_pos(self, *args):
# calculate new pos
invert_x = "r" in self.anchor
invert_y = "t" in self.anchor
self._pos = (
self.pos[0] - self._size[0] if invert_x else 0,
self.pos[1] - self._size[1] if invert_y else 0
)
def on_size(self, *args):
anim = Animation(
_size=self.size if self.opened else (0, 0),
duration=0.5,
transition="in_out_circ"
)
anim.start(self)
def open(self, *args):
# toggle the value of open state
self.opened = not self.opened
Builder.load_string(KV)

if __name__ == "__main__":
from kivy.app import runTouchApp
from kivy.uix.button import Button
from kivy.core.window import Window
class Test(Button):
def __init__(self, **kwargs):
super(Test, self).__init__(**kwargs)
self.size = (100, 100)
self.size_hint = (None, None)
self.dropdown = DropDown(pos=(200, 100), size=(400, 300))
self.add_widget(self.dropdown)
self.bind(on_release=lambda *args: self.dropdown.open(self))
Window.clearcolor = (1, 1, 1, 1)
runTouchApp(Test())

您可能需要在DropDown上设置size_hint: None, None。如果size_hint不是"无",则它将覆盖任何size设置(包括size属性的动画(。

相关内容

最新更新