Kivy:改变方向时改变布局

时间:2015-03-28 14:50:58

标签: python widget kivy

我希望创建一些在窗口的方向或大小发生变化时更改其总体布局的内容。在下面的例子中,我试图用3个按钮来做这件事。但它失败了,并且当我尝试将它们添加到布局时,抱怨按钮已经有了父项。为什么他们已经有了父母?我从未将它们添加到AdaptWidget中...... 更重要的是,应该如何实现我想要实现的目标? 代码如下:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout

class AdaptWidget(BoxLayoutWrite failed: Broken pipe
    def __init__(self, **kw):
        super(AdaptWidget, self).__init__(**kw)
        self.but1 = Button(text='but1')
        self.but2 = Button(text='but2')
        self.but3 = Button(text='but3')
        self.layout = None

    def on_size(self, *args):
        self.clear_widgets()

        if self.size[0] > self.size[1]:
            self.layout = BoxLayout(orientation='horizontal')
            self.but1.size_hint = 0.7, 1

            self.layout.add_widget(self.but1)
            vert = BoxLayout(orientation='vertical')
            self.layout.add_widget(vert)
            self.but2.size_hint = (1,0.5)
            self.but3.size_hint = (1,0.5)
            vert.add_widget(self.but2)
            vert.add_widget(self.but3)
        else:
            self.layout = BoxLayout(orientation='vertical')
            self.but1.size_hint = 1, 0.7
            self.layout.add_widget(self.but1)
            horiz = BoxLayout(oreintation='horizontal')
            self.layout.add_widget(horiz)
            self.but2.size_hint = 0.5, 1
            self.but3.size_hint = 0.5, 1
            horiz.add_widget(self.but2)
            horiz.add_widget(self.but3)

        self.add_widget(self.layout)

class TestLayoutApp(App):
    def build(self):
        return AdaptWidget()

if __name__ == '__main__':
    TestLayoutApp().run()

2 个答案:

答案 0 :(得分:1)

每次AdaptWidget的大小发生变化时,您的on_size回调都会运行 - 但回调系统不会从其父级中移除任何小部件,因此on_size将始终崩溃第二次被召唤。您始终可以确保从其父级删除窗口小部件:

if widget.parent is not None:
    widget.parent.remove_widget(widget)

答案 1 :(得分:0)

  1. 编辑:

3天前,我写了这个“答案”,尽管我无法使以上建议生效。

但是现在有人在这里:https://groups.google.com/forum/#!topic/kivy-users/Z5fjt5tNys8 向我展示了如何做。

因此解决方案来了:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout


class AdaptWidget(BoxLayout):

    def __init__(self, **kw):
        super(AdaptWidget, self).__init__(**kw)
        # but1 = Button(id='but1', text='button1')
        # but1 = ObjectProperty(None)
        # self.but1 = ObjectProperty(None)
        self.add_widget(Button(id='but1', text='button1'))
        self.add_widget(Button(id='but2', text='button2'))
        self.add_widget(Button(id='but3', text='button3'))

    def on_size(self, *args):
        if self.width > self.height:
            self.orientation = 'horizontal'
            # self.child.but1.size_hint = (0.7, 1)
            # but1.size_hint = (0.7, 1)
            # self.ids.but1.size_hint = (0.7, 1)
            self.children[2].size_hint = (0.7, 1)
            self.children[1].size_hint = (0.5, 1)
            self.children[0].size_hint = (0.5, 1)
        else:
            self.orientation = 'vertical'
            self.children[2].size_hint = (1, 0.7)
            self.children[1].size_hint = (1, 0.5)
            self.children[0].size_hint = (1, 0.5)


class TestLayoutApp(App):
    def build(self):
        return AdaptWidget()


if __name__ == '__main__':
    TestLayoutApp().run()

请注意,以上解决方案比原始代码干净得多。无需删除或清除任何小部件。您只需更改其属性即可。

  1. 编辑:

部分问题是“ buildozer.spec”文件包含以下内容:

# (str) Supported orientation (one of landscape, sensorLandscape, portrait or all)
orientation = portrait

代替此:

# (str) Supported orientation (one of landscape, sensorLandscape, portrait or all)
orientation = all