Скрытие и отображение виджета в Kivy

Я работаю над проектом Kivy, и мне нужно отобразить метку, когда в списке нет элементов. В противном случае мне нужно отобразить представление списка.

вот два сценария, которые я описываю:

когда нет друзей, чтобы показать: No friends

когда список содержит друзьям: List with friends

Это мой файл Kivy:

#: kivy 1.9.1
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
#: import FriendItemButton gui.FriendItemButton

ChumMeRoot:

<ChumMeRoot>:
    friend_list_view: friend_list_view
    FriendList:
        id: friend_list_view


<FriendItemButton>:
    text: self.full_name
    height: "40dp"
    size_hint_y: None


<FriendList>:
    orientation: 'vertical'
    friend_list: friend_list_view
    Button:
        height: '45dp'
        size_hint_y: None
        text: 'Add Friend'
        on_press: app.root.show_add_friend_form()
    ListView:
        id: friend_list_view
        adapter:
            ListAdapter(
            data=[],
            cls=FriendItemButton,
            args_converter=root.args_converter)


<AddFriendFormInput@BoxLayout>
    height: '30dp'
    size_hint_y: None


<AddFriendForm>:
    orientation: 'vertical'
    first_name_input: first_name
    last_name_input: last_name
    AddFriendFormInput:
        Label:
            text: 'First Name'
        TextInput:
            id: first_name
    AddFriendFormInput:
        Label:
            text: 'Middle Name'
        TextInput:
    AddFriendFormInput:
        Label:
            text: 'Last Name'
        TextInput:
            id: last_name
    AddFriendFormInput:
        Label:
            text: 'Birthdate'
        TextInput:
    AddFriendFormInput:
        Label:
            text: 'Email'
        TextInput:
    AddFriendFormInput:
        Label:
            text: 'Cell Phone'
        TextInput:
    BoxLayout:
    BoxLayout:
        height: '40dp'
        size_hint_y: None
        Button:
            text: 'Cancel'
            on_press: app.root.show_friend_list()
        Button:
            text: 'Add friend'
            on_press: app.root.add_friend()

и это мой Python код:

import os

from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.listview import ListItemButton

from friend import Friend
from friend_manager import FriendManager


def get_friend_manager():
    db_path = '{}/{}'.format(
        os.path.dirname(os.path.abspath(__file__)),
        'chumme.db'
    )
    return FriendManager(db_path)

def get_friends():
    return [(friend.full_name,)
            for friend in get_friend_manager().get_friends()]


class ChumMeRoot(BoxLayout):
    add_friend_form = ObjectProperty()
    friend_list_view = ObjectProperty()

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

    def update_friend_list_view(self):
        friend_list = self.friend_list_view.friend_list
        friend_list.adapter.data.clear()
        friend_list.adapter.data.extend(get_friends())
        friend_list._trigger_reset_populate()

    def show_add_friend_form(self):
        self.clear_widgets()
        self.add_friend_form = AddFriendForm()
        self.add_widget(self.add_friend_form)

    def show_friend_list(self):
        self.clear_widgets()
        self.update_friend_list_view()
        self.add_widget(self.friend_list_view)

    def add_friend(self):
        friend = Friend(first_name=self.add_friend_form.first_name_input.text,
                        last_name=self.add_friend_form.last_name_input.text)
        get_friend_manager().add_friend(friend)
        self.show_friend_list()


class AddFriendForm(BoxLayout):
    first_name_input = ObjectProperty()
    last_name_input = ObjectProperty()



class FriendList(BoxLayout):
    friend_list = ObjectProperty()

    def args_converter(self, index, data_item):
        return {'full_name': (data_item[0])}


class FriendItemButton(ListItemButton):
    full_name = StringProperty()


class ChumMeApp(App):
    pass


def main():
    ChumMeApp().run()


if __name__ == '__main__':
    main()

до сих пор я нашел данное решение который в основном говорит, чтобы избежать удаления виджетов из корня, и хотя я пробовал, я потерял ссылки и мое приложение падает. Я также не хочу помещать элемент в положение вне видимого экрана, поэтому мне интересно, знает ли кто-нибудь способ скрыть и показать виджеты как "я".widget_name.hide ()or self.widget_name.hide = True`, или кто-нибудь может сказать мне хороший способ достичь этой задачи?

1 ответов


как @yogabonito предложил, что я сделал, чтобы установить высоту виджета в этом случае 0dp (и, очевидно, атрибут size_hint_y.

так это изменения, которые я сделал в моем файле kivy:

<FriendList>:
    orientation: 'vertical'
    friend_list: friend_list_view
    no_friends_label: no_friends_label
    Button:
        height: '45dp'
        size_hint_y: None
        text: 'Add Friend'
        on_press: app.root.show_add_friend_form()
    Label:
        id: no_friends_label
    ListView:
        id: friend_list_view
        adapter:
            ListAdapter(
            data=[],
            cls=FriendItemButton,
            args_converter=root.args_converter)

как видно, я добавил виджет метки, который имеет ссылку в своем корне под названием no_friends_label.

это изменения, которые я сделал в моем файле Python:

class FriendList(BoxLayout):
    friend_list = ObjectProperty()
    no_friends_label = ObjectProperty()

    def args_converter(self, index, data_item):
        return {'full_name': (data_item[0])}

class ChumMeRoot(BoxLayout):
    add_friend_form = ObjectProperty()
    friend_list_view = ObjectProperty()

    # __init__ method

    def update_friend_list_view(self):
        friends = get_friends()
        no_friends_label = self.friend_list_view.no_friends_label
        friend_list = self.friend_list_view.friend_list

        if friends:
            friend_list.size_hint_y = 1
            friend_list.adapter.data.clear()
            friend_list.adapter.data.extend(friends)
            friend_list._trigger_reset_populate()
            no_friends_label.size_hint_y = None
            no_friends_label.height = '0dp'
            no_friends_label.text = ''
        else:
            no_friends_label = self.friend_list_view.no_friends_label
            no_friends_label.size_hint_y = 1
            no_friends_label.text = 'There are no friends to show.'
            friend_list.size_hint_y = None
            friend_list.height = '0dp'

     # remaining methods

во-первых, я добавил свойство kivy friend_list, который имеет соответствующую ссылка в файле kivy. Затем я "скрываю" или показываю метку или представление списка в зависимости от наличия у пользователя друзей.