【问题标题】:Hiding and showing a widget in Kivy在 Kivy 中隐藏和显示小部件
【发布时间】:2017-06-18 13:00:30
【问题描述】:

我正在做一个 Kivy 项目,当列表中没有元素时,我需要显示一个标签。否则,我需要显示一个列表视图。

这是我描述的两种情况:

当没有朋友可以显示时:

当列表包含朋友时:

这是我的 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()

到目前为止,我找到了this solution,它基本上说要避免从根目录中删除小部件,尽管我已经尝试过了,但我丢失了引用并且我的应用程序崩溃了。我也不想将元素放在可见屏幕之外的位置,所以我想知道是否有人知道隐藏和显示小部件的方法 'self.widget_name.hide()orself.widget_name.hide = True`,或者有人可以告诉我完成这项任务的好方法吗?

【问题讨论】:

  • 也许通过使其透明来隐藏小部件是您的一种选择。如果是这样,请查看opacity kwarg。另一种简单的方法是将小部件的大小设置为 0。
  • @yogabonito,将大小设置为 0 似乎不是一个坏主意。
  • 很高兴我的评论对你有用:)
  • @yogabonito,是的,我实际上根据您的帮助提供了回复。非常感谢。

标签: python kivy kivy-language


【解决方案1】:

应该适用于每个小部件和用例:

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

【讨论】:

    【解决方案2】:

    正如@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)
    

    可以看出,我添加了一个 Label 小部件,它在其根目录中有一个名为 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 文件中有相应的引用。然后我会根据用户的朋友来“隐藏”或显示标签或列表视图。

    【讨论】:

      【解决方案3】:

      在 Matteljay 的评论中,

      def hide_widget(wid, dohide=True):
      

      应该是

      def hide_widget(self, wid, dohide=True):
      

      有趣的是,如果没有 self , hide_widget 会隐藏整个应用程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-25
        • 2017-08-09
        • 2011-09-16
        • 2017-10-11
        • 2020-10-17
        • 2017-12-28
        • 2019-07-07
        • 1970-01-01
        相关资源
        最近更新 更多