Переключение виджетов kivy

Я использую библиотеку Kivy python.

у меня есть два виджета определенными.

когда программа запускается, я запускаю первый виджет.

когда эта кнопка виджетов нажата, я хочу, чтобы она исчезла и была заменена вторым виджетом.

здесь .кВ для двух виджетов

#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() более мощные, но экран берет много из ваших рук, Если вам интересно. Эффекты перехода тоже.

2 ответов


мое предложение - иметь виджет менеджера интерфейса, тогда вы можете иметь различные виджеты для ваших форм пользовательского интерфейса.

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

простой способ переключения виджетов-позволить одному быть полной высотой его контейнера, а второму иметь высоту нуля. Когда вам нужно переключиться просто поменять высоту вокруг.