问题描述
我使用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,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)
runTouchApp(test())
解决方法
您可能需要在size_hint: None,None
上设置DropDown
。如果size_hint
不为None,它将覆盖任何size
设置(包括size
属性的动画)。