Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hiding and showing a widget in Kivy

I am working on a Kivy project, and I need to display a label when there is no elements in a list. Otherwise, I need to display a list view.

These are the two scenarios I am describing:

When no friends to show: No friends

When list contains friends: List with friends

This is my Kivy file:

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

and this is my Python code:

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

So far, I have found this solution which basically says to avoid removing widgets from the root, and though I have tried it, I lost references and my app crashes. I don't also want to put the element in a position out of the visible screen, so I wonder if somebody knows a way to hide and show widgets as 'self.widget_name.hide()orself.widget_name.hide = True`, or can somebody tell me a good way to achieve this task?

like image 429
lmiguelvargasf Avatar asked Feb 01 '17 17:02

lmiguelvargasf


People also ask

How do I disable widgets on Kivy?

To do this we will use a Boolean statement from Kivy, disabled: True . Our focus here is main. kv. Every button you add into Kivy will read as disabled: False automatically, so there is no need to add the disabled method on each button.

What is POS hint in Kivy?

pos : pos stands for position i.e it is used to position the widget. By default (0, 0), the bottom-left corner of the screen is the default position of the button in kivy python.

What does padding do in Kivy?

The padding argument tells Kivy how much space there should be between the Layout and its children, whereas the spacing arguments tells it how much spacing there should be between the children. To create the buttons, we use a simple loop that loops over a small range of numbers.


1 Answers

Should work for every widget & use case:

def hide_widget(wid, dohide=True):
    if hasattr(wid, 'saved_attrs'):
        if not dohide:
            wid.height, wid.size_hint_y, wid.opacity, wid.disabled = wid.saved_attrs
            del wid.saved_attrs
    elif dohide:
        wid.saved_attrs = wid.height, wid.size_hint_y, wid.opacity, wid.disabled
        wid.height, wid.size_hint_y, wid.opacity, wid.disabled = 0, None, 0, True
like image 68
Matteljay Avatar answered Oct 15 '22 08:10

Matteljay