Kivy 手风琴:警告不足 space
Kivy Accordion: Not enough space warning
我正在尝试在 1366x768 显示器中使用 Kivy 和 Python 3.7 制作一个 accordion-based 菜单(以防有所不同)。代码似乎工作得很好,因为我得到了想要的输出。但是,我收到警告,指出手风琴中所有 children 的 space 不足(我假设)并且布局将中止,但事实并非如此:所有内容都是用大量 space。虽然这不是一个关键问题,因为一切都按预期显示,但我要么遗漏了一些明显的东西,要么对 kivy 如何生成屏幕元素有误解。所以,如果你能澄清这一点(并希望摆脱丑陋的警告),我将不胜感激!
下面是代码的简化版本,全部都是纯 python(我想保持这种状态,它不是一个复杂的程序)。我只是制作了一个外部 BoxLayout,并在内部放置了一个内部 GridLayout,手风琴下方有一个按钮。请注意,我将 kivy 设置为 运行 最大化 window,此设置包含在代码中。
起初我认为这可能与 kivy 处理项目的顺序有关:它可能首先检查标签和按钮假设默认 size_hint=(1, 1) 并认为它没有space,但由于自定义 size_hint,所以能够绘制它们。但是,当将其更改为 (1, 1) 时,我收到了相同的警告,同时仍然保留了使用 space 绘制的所有内容(尽管不是很多)。不过,它确实稍微改变了警告,因为它显示了更多警告和更严格的限制。
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.app import App
from kivy.config import Config
class TestApp(App):
def build(self):
layout = BoxLayout(orientation="vertical")
inner_layout = GridLayout(cols=3)
inner_layout.add_widget(Label(text="Section 1", size_hint=(1, 0.09), font_size='20dp'))
inner_layout.add_widget(Label(text="Section 2", size_hint=(1, 0.09), font_size='20dp'))
inner_layout.add_widget(Label(text="Section 3", size_hint=(1, 0.09), font_size='20dp'))
accord1 = Accordion(orientation="vertical")
accord1.add_widget(AccordionItem(title="Item 1"))
accord1.add_widget(AccordionItem(title="Item 2"))
accord2 = Accordion(orientation="vertical")
accord2.add_widget(AccordionItem(title="Item 1"))
accord3 = Accordion(orientation="vertical")
accord3.add_widget(AccordionItem(title="Item 1"))
accord3.add_widget(AccordionItem(title="Item 2"))
accord3.add_widget(AccordionItem(title="Item 3"))
inner_layout.add_widget(accord1)
inner_layout.add_widget(accord2)
inner_layout.add_widget(accord3)
layout.add_widget(inner_layout)
continue_btn = Button(text="START", size_hint=(1, 0.07))
layout.add_widget(continue_btn)
return layout
if __name__ == "__main__":
# Three lines to ensure non-fullscreen, maximized window on launch
Config.set('graphics', 'fullscreen', 0)
Config.set('graphics', 'borderless', 0)
Config.set('graphics', 'window_state', 'maximized')
Config.write()
TestApp().run()
这是我使用显示代码收到的警告:
[WARNING] [Accordion ] not enough space for displaying all children
[WARNING] [Accordion ] need 132px, got 91px
[WARNING] [Accordion ] layout aborted.
虽然这些是将所有 size_hint 值更改为默认值 (1, 1) 的结果:
[WARNING] [Accordion ] not enough space for displaying all children
[WARNING] [Accordion ] need 88px, got 50px
[WARNING] [Accordion ] layout aborted.
[WARNING] [Accordion ] not enough space for displaying all children
[WARNING] [Accordion ] need 132px, got 50px
[WARNING] [Accordion ] layout aborted.
您收到该警告的原因是 Accordion
小部件在设置其实际大小之前是 运行 其布局代码(Accordion
正常)。请注意,该消息显示 need 132px
。这是因为每个项目的默认最小大小是 44,而您的 accord3
有 3 children(3 乘以 44 是 132)。它还说 got 91px
。这是因为 parent GridLayout
的初始大小是 100 x 100(对于所有小部件都是如此),其中的 0.09(或 9px)被 Section 3
Label
,为 Accordion
留下 91px。由于91小于132,所以判定不够space。正确,但不久之后,布局代码以正确的值再次调用,一切正常。如果该代码的作者可以消除那些无意义的警告,那就太好了。
因此,您可以通过在 GridLayout
确定其实际大小之前不将 Accordion
小部件添加到布局来避免这些警告。为此,您可以使用 Clock.schedule_once()
。这是使用该方法对 TestApp
的修改:
class TestApp(App):
def build(self):
layout = BoxLayout(orientation="vertical")
self.inner_layout = GridLayout(cols=3)
self.inner_layout.add_widget(Label(text="Section 1", size_hint=(1, 0.09), font_size='20dp'))
self.inner_layout.add_widget(Label(text="Section 2", size_hint=(1, 0.09), font_size='20dp'))
self.inner_layout.add_widget(Label(text="Section 3", size_hint=(1, 0.09), font_size='20dp'))
layout.add_widget(self.inner_layout)
continue_btn = Button(text="START", size_hint=(1, 0.07))
layout.add_widget(continue_btn)
Clock.schedule_once(self.add_accordions)
return layout
def add_accordions(self, dt):
accord1 = Accordion(orientation="vertical")
accord1.add_widget(AccordionItem(title="Item 1"))
accord1.add_widget(AccordionItem(title="Item 2"))
accord2 = Accordion(orientation="vertical")
accord2.add_widget(AccordionItem(title="Item 1"))
accord3 = Accordion(orientation="vertical")
accord3.add_widget(AccordionItem(title="Item 1"))
accord3.add_widget(AccordionItem(title="Item 2"))
accord3.add_widget(AccordionItem(title="Item 3"))
self.inner_layout.add_widget(accord1)
self.inner_layout.add_widget(accord2)
self.inner_layout.add_widget(accord3)
我正在尝试在 1366x768 显示器中使用 Kivy 和 Python 3.7 制作一个 accordion-based 菜单(以防有所不同)。代码似乎工作得很好,因为我得到了想要的输出。但是,我收到警告,指出手风琴中所有 children 的 space 不足(我假设)并且布局将中止,但事实并非如此:所有内容都是用大量 space。虽然这不是一个关键问题,因为一切都按预期显示,但我要么遗漏了一些明显的东西,要么对 kivy 如何生成屏幕元素有误解。所以,如果你能澄清这一点(并希望摆脱丑陋的警告),我将不胜感激!
下面是代码的简化版本,全部都是纯 python(我想保持这种状态,它不是一个复杂的程序)。我只是制作了一个外部 BoxLayout,并在内部放置了一个内部 GridLayout,手风琴下方有一个按钮。请注意,我将 kivy 设置为 运行 最大化 window,此设置包含在代码中。
起初我认为这可能与 kivy 处理项目的顺序有关:它可能首先检查标签和按钮假设默认 size_hint=(1, 1) 并认为它没有space,但由于自定义 size_hint,所以能够绘制它们。但是,当将其更改为 (1, 1) 时,我收到了相同的警告,同时仍然保留了使用 space 绘制的所有内容(尽管不是很多)。不过,它确实稍微改变了警告,因为它显示了更多警告和更严格的限制。
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.app import App
from kivy.config import Config
class TestApp(App):
def build(self):
layout = BoxLayout(orientation="vertical")
inner_layout = GridLayout(cols=3)
inner_layout.add_widget(Label(text="Section 1", size_hint=(1, 0.09), font_size='20dp'))
inner_layout.add_widget(Label(text="Section 2", size_hint=(1, 0.09), font_size='20dp'))
inner_layout.add_widget(Label(text="Section 3", size_hint=(1, 0.09), font_size='20dp'))
accord1 = Accordion(orientation="vertical")
accord1.add_widget(AccordionItem(title="Item 1"))
accord1.add_widget(AccordionItem(title="Item 2"))
accord2 = Accordion(orientation="vertical")
accord2.add_widget(AccordionItem(title="Item 1"))
accord3 = Accordion(orientation="vertical")
accord3.add_widget(AccordionItem(title="Item 1"))
accord3.add_widget(AccordionItem(title="Item 2"))
accord3.add_widget(AccordionItem(title="Item 3"))
inner_layout.add_widget(accord1)
inner_layout.add_widget(accord2)
inner_layout.add_widget(accord3)
layout.add_widget(inner_layout)
continue_btn = Button(text="START", size_hint=(1, 0.07))
layout.add_widget(continue_btn)
return layout
if __name__ == "__main__":
# Three lines to ensure non-fullscreen, maximized window on launch
Config.set('graphics', 'fullscreen', 0)
Config.set('graphics', 'borderless', 0)
Config.set('graphics', 'window_state', 'maximized')
Config.write()
TestApp().run()
这是我使用显示代码收到的警告:
[WARNING] [Accordion ] not enough space for displaying all children
[WARNING] [Accordion ] need 132px, got 91px
[WARNING] [Accordion ] layout aborted.
虽然这些是将所有 size_hint 值更改为默认值 (1, 1) 的结果:
[WARNING] [Accordion ] not enough space for displaying all children
[WARNING] [Accordion ] need 88px, got 50px
[WARNING] [Accordion ] layout aborted.
[WARNING] [Accordion ] not enough space for displaying all children
[WARNING] [Accordion ] need 132px, got 50px
[WARNING] [Accordion ] layout aborted.
您收到该警告的原因是 Accordion
小部件在设置其实际大小之前是 运行 其布局代码(Accordion
正常)。请注意,该消息显示 need 132px
。这是因为每个项目的默认最小大小是 44,而您的 accord3
有 3 children(3 乘以 44 是 132)。它还说 got 91px
。这是因为 parent GridLayout
的初始大小是 100 x 100(对于所有小部件都是如此),其中的 0.09(或 9px)被 Section 3
Label
,为 Accordion
留下 91px。由于91小于132,所以判定不够space。正确,但不久之后,布局代码以正确的值再次调用,一切正常。如果该代码的作者可以消除那些无意义的警告,那就太好了。
因此,您可以通过在 GridLayout
确定其实际大小之前不将 Accordion
小部件添加到布局来避免这些警告。为此,您可以使用 Clock.schedule_once()
。这是使用该方法对 TestApp
的修改:
class TestApp(App):
def build(self):
layout = BoxLayout(orientation="vertical")
self.inner_layout = GridLayout(cols=3)
self.inner_layout.add_widget(Label(text="Section 1", size_hint=(1, 0.09), font_size='20dp'))
self.inner_layout.add_widget(Label(text="Section 2", size_hint=(1, 0.09), font_size='20dp'))
self.inner_layout.add_widget(Label(text="Section 3", size_hint=(1, 0.09), font_size='20dp'))
layout.add_widget(self.inner_layout)
continue_btn = Button(text="START", size_hint=(1, 0.07))
layout.add_widget(continue_btn)
Clock.schedule_once(self.add_accordions)
return layout
def add_accordions(self, dt):
accord1 = Accordion(orientation="vertical")
accord1.add_widget(AccordionItem(title="Item 1"))
accord1.add_widget(AccordionItem(title="Item 2"))
accord2 = Accordion(orientation="vertical")
accord2.add_widget(AccordionItem(title="Item 1"))
accord3 = Accordion(orientation="vertical")
accord3.add_widget(AccordionItem(title="Item 1"))
accord3.add_widget(AccordionItem(title="Item 2"))
accord3.add_widget(AccordionItem(title="Item 3"))
self.inner_layout.add_widget(accord1)
self.inner_layout.add_widget(accord2)
self.inner_layout.add_widget(accord3)