切换kivy控件

9 投票
2 回答
9846 浏览
提问于 2025-04-17 14:46

我正在使用Kivy这个Python库。

我定义了两个小部件(widgets)。

当程序运行时,我先显示第一个小部件。

当这个小部件的按钮被按下时,我希望它消失,并被第二个小部件替代。

下面是这两个小部件的.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.

这里的想法是有一个用户界面管理器。这个管理器不是像树一样运行用户界面,而是像列表和栈一样。列表中保存了我所有用户界面表单的实例,而栈则保存了这些表单的遍历记录。每当我们跳转到一个表单时,就把它推入栈中,并“渲染”或者说显示那个表单。

编辑:我选择了我的答案,但在搜索中我也发现了Screen对象:http://kivy.org/docs/api-kivy.uix.screenmanager.html。个人觉得,clear()和add()命令更强大,但如果你感兴趣的话,Screen会帮你处理很多事情,包括过渡效果。

2 个回答

5

一种简单的切换小部件的方法是让一个小部件的高度占满整个容器,而另一个小部件的高度设置为零。这样,当你需要切换时,只需互换它们的高度就可以了。

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()

当然,你不会像那样来组织它。你可以把所有的表单放在一个字典里,字典放在容器对象上,然后用一个通用的回调函数,通过键来提供另一个表单。

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])

撰写回答