切换kivy小部件

9
我正在使用Kivy Python库。
我定义了两个小部件。
程序运行时,我运行第一个小部件。
当该小部件的按钮被按下时,我希望它消失并被第二个小部件替换。
这是两个小部件的.kv文件。
#uitest.kv
<TestForm>:
    canvas:
        Rectangle:
            pos: self.center_x, 0
            size: 10, self.height

    BoxLayout:
        size: root.size
        padding: 40
        Button:
            text: 'Hello'
            on_release: root.testCallback()

<TestForm2>:
    canvas:
        Rectangle:
            pos: self.center_x, 0
            size: self.height, 10

我的主要Python文件运行应用程序,并返回第一个小部件。
#main.py
from testform import TestForm
from kivy.app import App

class UITestApp(App):
    def build(self):
        return TestForm()

# Main launching point
if __name__ in ('__main__', '__android__'):
    UITestApp().run()

我的第一个小部件有一个回调函数。这就是代码所属的地方。

from testform2 import TestForm2
from kivy.uix.widget import Widget

class TestForm(Widget):
    def testCallback(self):
        TestForm2() # Code in question goes here. @TODO replace this widget with TestForm2 widget.

这里的想法是拥有一个用户界面管理器。该管理器不像树一样运行UI,而是像列表和堆栈一样运行。列表包含所有UI表单的实例。堆栈保存了这些表单的遍历,每当我们跳转到一个表单时,便将其推入堆栈并“渲染”或其他操作。
编辑: 我选择了我的答案,但在搜索中我还发现了Screen对象:http://kivy.org/docs/api-kivy.uix.screenmanager.html。个人认为,清除(clear())和添加(add())命令更加强大,但如果您感兴趣,屏幕(screen)可以帮助您解决很多问题,还有过渡效果。
2个回答

11

我的建议是添加一个界面管理器小部件,然后你就可以为你的用户界面表单使用各种小部件。

import kivy
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App

class InterfaceManager(BoxLayout):

    def __init__(self, **kwargs):
        super(InterfaceManager, self).__init__(**kwargs)

        self.first = Button(text="First")
        self.first.bind(on_press=self.show_second)

        self.second = Button(text="Second")
        self.second.bind(on_press=self.show_final)

        self.final = Label(text="Hello World")
        self.add_widget(self.first)

    def show_second(self, button):
        self.clear_widgets()
        self.add_widget(self.second)

    def show_final(self, button):
        self.clear_widgets()
        self.add_widget(self.final)


class MyApp(App):
    def build(self):
        return InterfaceManager(orientation='vertical')

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

当然,你不会这样构建它。你可以在Container对象中保存所有的表单,并拥有一个通用的回调函数,它通过键提供另一个表单。

class InterfaceManager(BoxLayout):

    def __init__(self, **kwargs):
        super(InterfaceManager, self).__init__(**kwargs)
        self.forms = {}

    def add_form(self, key, form):
        self.forms[key] = form

    def uniCallback(self, button):
        self.clear_widgets()
        # You could introduce a more elegant key
        # handling system here.
        self.add_widget(self.forms[button.text])

clear_widgets()和add_widget()是我缺失的秘密命令,非常感谢。无论搜索多少次都找不到它们,只有“screen”对象。 - MintyAnt
2
文档对于kivy来说非常优秀,浏览右侧列出的所有不同小部件可能是值得的。当我第一次发现这个库时,有很多东西我都在试图重新发明。 - Adam
2
你能用Kivy语言给出相同的代码吗?将Kivy语言与Python混合使用让我感到困惑! - Wally
@user3620828:可能值得提出另一个问题。记得提供你已经尝试过的例子。 - Adam

5

一种简单的切换小部件的方法是让一个小部件的高度与其容器的高度相同,而将第二个小部件的高度设置为零。当需要切换时,只需交换它们的高度即可。


当然是一个有趣的选项!但我计划拥有许多小部件,如果我想从内存中清除一些小部件,这可能不是最好的选择。 - MintyAnt
@MintyAnt,在我的应用程序中,我只有2个小部件可供切换,这种方法对我很有效。很抱歉它不适合你的用例。 - Mark Ransom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接