Kivymd:如何在不创建自定义类的情况下在列表项中添加复选框?

Posted

技术标签:

【中文标题】Kivymd:如何在不创建自定义类的情况下在列表项中添加复选框?【英文标题】:Kivymd: How to add checkbox in List item without creating custom class? 【发布时间】:2021-11-22 00:15:43 【问题描述】:

如何添加带有 MDList 项目的复选框?在我的项目中,我需要一个事件,“单击按钮后将所选项目文本存储在 python 列表中”。当我为带有复选框的列表创建自定义类时,可以轻松完成(如 kivymd 文档中所示)。

from kivy.lang import Builder

from kivy.properties import StringProperty
from kivymd.app import MDApp
from kivymd.uix.list import IRightBodyTouch, TwoLineAvatarIconListItem
from kivymd.uix.selectioncontrol import MDCheckbox

KV = """
<ListItemWithCheckbox>:
    IconLeftWidget:
        icon: root.icon
    RightCheckbox:
        id: cb

BoxLayout:

    ScrollView:

        MDList:
            id: scroll
            
    MDRaisedButton:
        text: "Save"
        on_release: app.save_checked()
"""

class ListItemWithCheckbox(TwoLineAvatarIconListItem):
    """Custom list item."""
    icon = StringProperty("android")

class RightCheckbox(IRightBodyTouch, MDCheckbox):
    """Custom right container."""

class MainApp(MDApp):
    def build(self):
        return Builder.load_string(KV)

    def on_start(self):
        for i in range(15):
            self.root.ids.scroll.add_widget(
                ListItemWithCheckbox(text=f"Item i", secondary_text=f"Item i+10", icon='User_images/s.jpg')
            )
    def save_checked(self):
        mdlist = self.root.ids.scroll  # get reference to the MDList
        selected_item = []
        for wid in mdlist.children:
            if isinstance(wid, ListItemWithCheckbox):  # only interested in the ListItemWithCheckboxes
                cb = wid.ids.cb  # use the id defined in kv
                if cb.active:  # only append selected items

                    selected_item.append(wid.text)
        selected_item = selected_item[::-1]
        print(selected_item)


MainApp().run()

当我尝试使用屏幕管理器(用于处理多个屏幕)应用这个东西时,它不起作用。我可以在不为列表创建自定义类的情况下创建带有复选框的列表吗?

注意:我的要求是,我需要一个带有复选框的列表。按下按钮选择列表项后,应打印所选项目(或用于其他目的)

【问题讨论】:

【参考方案1】:

为了在没有自定义类的情况下做到这一点,请使用答案末尾的示例:

from kivy.lang import Builder

from kivy.properties import StringProperty
from kivymd.app import MDApp
from kivymd.uix.list import IRightBodyTouch, TwoLineAvatarIconListItem
from kivymd.uix.selectioncontrol import MDCheckbox

KV = """
<CB@TwoLineAvatarIconListItem>:
    IconLeftWidget:
        id: i1
        icon: "pencil" #root.icon
    IconRightWidget:
        icon: "a11.png" #this is a transparent png image of 188 bytes
        MDCheckbox:
            id: x54
            on_active:
                app.save_checked(*args,root.text,root.secondary_text,root.ids.i1.icon,root)

BoxLayout:
    ScrollView:
        MDList:
            id: scroll
            #for i in range(15)#
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello jbsidis"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Josue Carranza"
                secondary_text: "jbsidis"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            CB:
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
            
    MDRaisedButton:
        id: cm
        text: "Save"
        on_release: app.save_checked()
"""

selected_item = []
class MainAppjbsidis(MDApp):
    def build(self):
        return Builder.load_string(KV)

    def save_checked(self,checkbox, value,a,b,c,w):
        mmm="""
            You clicked on:  Josue Carranza jbsidis
            Selected Items 4: [[<WeakProxy to <kivy.factory.CB object at 0x7efc032f4430>>], [<WeakProxy to <kivy.factory.CB object at 0x7efc032f4430>>], [<WeakProxy to <kivy.factory.CB object at 0x7efc0324d9e0>>], [<WeakProxy to <kivy.factory.CB object at 0x7efc03137b30>>]]
            """
        if value:
            print('The checkbox is active', 'and', checkbox.state, 'state')
            global selected_item
            if len(selected_item)==0:
                selected_item = []
                selected_item.append([w])
                print("\n\nYou clicked on: ",a,b,c)
                print("Selected Items "+str(len(selected_item))+": "+str(selected_item))
            if len(selected_item)>0:
                selected_item.append([w])
                print("\n\nYou clicked on: ",a,b,c)
                print("Selected Items "+str(len(selected_item))+": "+str(selected_item))
                self.root.ids.cm.text="Save "+str(len(selected_item))
        else:
            print('\n\nThe checkbox is inactive', 'and', checkbox.state, 'state')
            new_list=[]
            if len(selected_item)>0:
                for x in selected_item:
                    if x==w:
                        pass
                    if x!=w:
                        new_list=new_list+[w]
                selected_item=new_list
                
                print("\n\nNew Items: "+str(selected_item))
                
MainAppjbsidis().run()

图片:

如果您不想拥有任何自定义类,例如:

<CB@TwoLineAvatarIconListItem>:
    IconLeftWidget:
        id: i1
        icon: "pencil" #root.icon
    IconRightWidget:
        icon: "a11.png" #this is a transparent png image of 188 bytes
        MDCheckbox:
            id: x54
            on_active:
                app.save_checked(*args,root.text,root.secondary_text,root.ids.i1.icon,root)

你应该使用 do it with:

from kivy.lang import Builder

from kivy.properties import StringProperty
from kivymd.app import MDApp
from kivymd.uix.list import IRightBodyTouch, TwoLineAvatarIconListItem
from kivymd.uix.selectioncontrol import MDCheckbox

KV = """
BoxLayout:
    ScrollView:
        MDList:
            id: scroll
            #for i in range(15)#
            TwoLineAvatarIconListItem:
                id: mm1
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
                IconLeftWidget:
                    id: i1
                    icon: "pencil" #root.icon
                IconRightWidget:
                    icon: "a11.png" #this is a transparent png image of 188 bytes
                    MDCheckbox:
                        id: x54
                        on_active:
                            app.save_checked(*args,root.ids.mm1.text,root.ids.mm1.secondary_text,root.ids.i1.icon,root)

            TwoLineAvatarIconListItem:
                id: mm2
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
                IconLeftWidget:
                    id: i1
                    icon: "pencil" #root.icon
                IconRightWidget:
                    icon: "a11.png" #this is a transparent png image of 188 bytes
                    MDCheckbox:
                        id: x54
                        on_active:
                            app.save_checked(*args,root.ids.mm2.text,root.ids.mm2.secondary_text,root.ids.i1.icon,root)

            TwoLineAvatarIconListItem:
                id: mm3
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
                IconLeftWidget:
                    id: i1
                    icon: "pencil" #root.icon
                IconRightWidget:
                    icon: "a11.png" #this is a transparent png image of 188 bytes
                    MDCheckbox:
                        id: x54
                        on_active:
                            app.save_checked(*args,root.ids.mm3.text,root.ids.mm3.secondary_text,root.ids.i1.icon,root)

            TwoLineAvatarIconListItem:
                id: mm4
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
                IconLeftWidget:
                    id: i1
                    icon: "pencil" #root.icon
                IconRightWidget:
                    icon: "a11.png" #this is a transparent png image of 188 bytes
                    MDCheckbox:
                        id: x54
                        on_active:
                            app.save_checked(*args,root.ids.mm4.text,root.ids.mm4.secondary_text,root.ids.i1.icon,root)

            TwoLineAvatarIconListItem:
                id: mm5
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
                IconLeftWidget:
                    id: i1
                    icon: "pencil" #root.icon
                IconRightWidget:
                    icon: "a11.png" #this is a transparent png image of 188 bytes
                    MDCheckbox:
                        id: x54
                        on_active:
                            app.save_checked(*args,root.ids.mm5.text,root.ids.mm5.secondary_text,root.ids.i1.icon,root)

            TwoLineAvatarIconListItem:
                id: mm6
                text: "Hello"
                secondary_text: "Two"
                icon: "pencil"
                IconLeftWidget:
                    id: i1
                    icon: "pencil" #root.icon
                IconRightWidget:
                    icon: "a11.png" #this is a transparent png image of 188 bytes
                    MDCheckbox:
                        id: x54
                        on_active:
                            app.save_checked(*args,root.ids.mm6.text,root.ids.mm6.secondary_text,root.ids.i1.icon,root)

            
    MDRaisedButton:
        id: cm
        text: "Save"
        on_release: app.save_checked()
"""

selected_item = []
class MainAppjbsidis(MDApp):
    def build(self):
        return Builder.load_string(KV)

    def save_checked(self,checkbox, value,a,b,c,w):
        mmm="""
            You clicked on:  Josue Carranza jbsidis
            Selected Items 4: [[<WeakProxy to <kivy.factory.CB object at 0x7efc032f4430>>], [<WeakProxy to <kivy.factory.CB object at 0x7efc032f4430>>], [<WeakProxy to <kivy.factory.CB object at 0x7efc0324d9e0>>], [<WeakProxy to <kivy.factory.CB object at 0x7efc03137b30>>]]
            """
        if value:
            print('The checkbox is active', 'and', checkbox.state, 'state')
            global selected_item
            if len(selected_item)==0:
                selected_item = []
                selected_item.append([w])
                print("\n\nYou clicked on: ",a,b,c)
                print("Selected Items "+str(len(selected_item))+": "+str(selected_item))
            if len(selected_item)>0:
                selected_item.append([w])
                print("\n\nYou clicked on: ",a,b,c)
                print("Selected Items "+str(len(selected_item))+": "+str(selected_item))
                self.root.ids.cm.text="Save "+str(len(selected_item))
        else:
            print('\n\nThe checkbox is inactive', 'and', checkbox.state, 'state')
            new_list=[]
            if len(selected_item)>0:
                for x in selected_item:
                    if x==w:
                        pass
                    if x!=w:
                        new_list=new_list+[w]
                selected_item=new_list
                
                print("\n\nNew Items: "+str(selected_item))
                
MainAppjbsidis().run()

没有客户类的图片:

【讨论】:

编辑:当我输入错误的“客户类”时,我的意思是“自定义类” 谢谢你。但我仍然遇到问题。在实时应用程序中,我需要在 python 文件中创建列表项,然后将所有列表项添加到 .kv 文件中的列表中。你能告诉我解决这个问题的方法吗?注意:尝试在每个列表项中添加复选框时出现错误。 是的,如果您需要将选定的项目移动到新屏幕(到新列表),您应该使用“selected_item”全局变量并将这些选定的项目添加到新的MDList中屏幕,请记住,因为它是一个列表,您可以使用 for 循环将这些选定的项目添加到新屏幕,或者只是将值(而不是现在的小部件)保存为纯文本字符串,然后解析那些在新屏幕中,具体取决于您需要做什么 行 "icon: "a11.png" #this is an transparent png image of 188 bytes" 需要复选框干净并准备好使用,下载一个应该透明的 png 图像 好的,我明白了。如果你能帮助我在这个脚本中实现它,那对我来说会非常好---------> github.com/Shourov1702040/hpylearners_Python/blob/main/…

以上是关于Kivymd:如何在不创建自定义类的情况下在列表项中添加复选框?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不大幅增加其大小的情况下在 PowerShell 中保存文本文件?

如何在不定义任何限制的情况下在 python 中获取任意数量的输入?

如何在不使用 System.Net 类的情况下在 C# 中发送 HTTP 请求? [复制]

如何在不使用swiftUI附带的幻灯片删除的情况下创建自定义删除按钮我没有使用列表,只是使用foreach循环

在不创建新类的情况下访问自定义 UITableViewCell 中的 UITextField?

如何在不中断删除的情况下在 SwiftUI 中实现 TextField 列表