我对kivy和python还是很陌生,这里的第一个问题...因此,如果复选框为空,则我想隐藏布局,以操纵大小和不透明度属性。如果您使用复选框,它会按预期工作,但是在应用运行时,将有空白空间。我试图使用构造函数和schedule_once函数将大小更改为[0,0],并且看起来像size属性发生了变化,但是仍然可以在屏幕截图中看到一个空白空间。
P.S。 我有一个假设,即与kv文件相关的问题包括在内,因为我试图为此问题创建一个简约的示例,并且...仅使用main.kv和main.py即可正常工作。
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager
kivy.require('1.11.0')
kv = """
#:import utils kivy.utils
<ValuesGridLayout@GridLayout>:
cols: 1
row_default_height: 30
size_hint_y: None
height: self.minimum_height
spacing: 3
<MainPanelLabel@Label>:
text_size: self.size
valign: "middle"
padding_x: 5
text: "Some content"
<MainPanel>:
kinetic_container: kinetic_container
thread_container: thread_container
padding: 20, 20, 20, 0
BoxLayout:
orientation: 'vertical'
BoxLayout:
ScrollView:
GridLayout:
padding: [0, 10]
cols: 1
spacing: 30
size_hint_y: None
height: self.minimum_height
BoxLayout:
CheckBox:
size_hint: (None, None)
size: [20,20]
on_active:
root.toggleParameters(self.active, root.kinetic_container)
MainPanelLabel:
text: "Kinetic values:"
color: utils.get_color_from_hex('#f6711b')
font_size: '20sp'
ValuesGridLayout:
id: kinetic_container
visible: False
size: [500, 200] if self.visible else [0, 0]
opacity: 1 if self.visible else 0
disabled: not self.visible
MainPanelLabel
MainPanelLabel
MainPanelLabel
MainPanelLabel
MainPanelLabel
MainPanelLabel
BoxLayout:
CheckBox:
padding: 20
size_hint: (None, None)
size: [20,20]
on_active:
root.toggleParameters(self.active, root.thread_container)
MainPanelLabel:
text: "Thread values:"
color: utils.get_color_from_hex('#f6711b')
font_size: '20sp'
ValuesGridLayout:
id: thread_container
visible: False
size: [500, 200] if self.visible else [0, 0]
opacity: 1 if self.visible else 0
disabled: not self.visible
MainPanelLabel
MainPanelLabel
MainPanelLabel
MainPanelLabel
MainPanelLabel
<MainFrame>:
id: screen_manager
Screen:
name: "Initial"
MainPanel
"""
class MainPanel(BoxLayout):
def __init__(self, **kwargs):
super(MainPanel, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: self.initializeSize(), 0)
def toggleParameters(self, instance, object):
if instance:
object.visible = True
else:
object.visible = False
def initializeSize(self):
self.kinetic_container.size = [0, 0]
self.thread_container.size = [0, 0]
class MainFrame(ScreenManager):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class SomeApp(App):
def build(self):
return MainFrame()
if __name__ == "__main__":
Builder.load_string(kv)
SomeApp().run()
预先感谢!
答案 0 :(得分:0)
我不确定什么会导致越野车行为,但这是罪魁祸首。
<ValuesGridLayout@GridLayout>:
size_hint_y: None
height: self.minimum_height
...
在这里,您将高度设置为self.minimum_height
。但是,当您使用小部件时,您将覆盖它:
ValuesGridLayout:
id: kinetic_container
size: [500, 200] if self.visible else [0, 0]
...
(注意:设置宽度实际上没有任何作用,因为size_hint_x
仍为1。)
推测:如果值不同,则属性仅调度事件。当我尝试调试它时,在应用程序启动时,首先调用
height
的类定义,然后调用实例定义,然后再次调用类定义。如果您使用的是self.minimum_height
而不是200
,那么它会起作用,因此,看起来像是由更改调度的事件在初始窗口小部件设置期间触发了某些事件。
您可以将所有属性移到类规则中:
<ValuesGridLayout@GridLayout>:
visible: False
size_hint_y: None
height: self.minimum_height if self.visible else 0
opacity: 1 if self.visible else 0
disabled: not self.visible
cols: 1
row_default_height: 30
spacing: 3
现在您只需要
ValuesGridLayout:
id: kinetic_container
MainPanelLabel
...
和
ValuesGridLayout:
id: thread_container
MainPanelLabel
...
仅此而已。
size
,padding
(ReferenceListProperty
)与元组一起工作,因此您只需执行size: 200, 500
root.kinetic_container
,只需执行kinetic_container
,有关ID的范围,请参见docs toggleParameters()
是不必要的,您只需执行on_active: kinetic_container.visible = self.active
__init__()
class MainFrame(ScreenManager):
pass
黑客很开心!