Python KivyMD:如何在 MDCheckboxes 上使用 on_active?

Python KivyMD: How is it possible to use on_active on MDCheckboxes?

我目前在使用 MDCheckbox 时遇到了一些问题。当我使用默认的 Kivy Checkbox 时,kv 代码中的 on_active 参数似乎工作得很好。但是现在我正在尝试将 KivyMD MDCheckbox 模块与 MDList 一起使用,并尝试通过 on_active 参数向复选框添加一个功能:

部分kv代码

#:kivy 1.11.0
#:import MDCard kivymd.card.MDCard
#:import MDCheckbox kivymd.selectioncontrols.MDCheckbox
#:import MDList kivymd.list.MDList
#:import OneLineAvatarIconListItem kivymd.list.OneLineAvatarIconListItem

<ListItemWithCheckbox@OneLineAvatarIconListItem>:
    MyAvatar:
        source: 'src/hdl.jpg'
    MyCheckbox:

<LayoutPy>
    orientation: 'vertical'

    FloatLayout:

        MDCard:
            size_hint: .8, .5
            pos_hint: {'center_x': 0.5, 'center_y': 0.5}

            BoxLayout:
                orientation: 'horizontal'
                spacing: 20
                name: 'lists'

                ScrollView:

                    MDList:
                        id: scroll

                        ListItemWithCheckbox:
                            id: ckbx1
                            text: 'Box 1'
                            active: False
                            on_active: root.printS('Text 1')


                        ListItemWithCheckbox:
                            id: ckbx2
                            text: 'Box 2'
                            active: False
                            on_active: root.printS('Text 2')

                        ListItemWithCheckbox:
                            id: ckbx3
                            text: 'Box 3'
                            active: False
                            on_active: root.printS('Text 3')

部分Python代码

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivymd.theming import ThemeManager
from kivy.uix.image import Image
from kivymd.list import IRightBodyTouch, ILeftBody
from kivymd.selectioncontrols import MDCheckbox
from kivy.lang import Builder

class LayoutPy(FloatLayout):
    def __init__(self, **kwargs):
        super(LayoutPy, self).__init__(**kwargs)

    def printS(self, text):
        print(text)

class MyCheckbox(IRightBodyTouch, MDCheckbox):
    pass


class MyAvatar(ILeftBody, Image):
    pass

Builder.load_file(design.kv)

class KivyGUI(App):
    theme_cls = ThemeManager()
    theme_cls.primary_palette = ("Teal")
    title = ("App")

    def build(self):
        c = LayoutPy()
        return c

if __name__ == "__main__":
    KivyGUI().run()

我认为与普通的 Kivy 不同,KivyMD 需要一个额外的 active 参数来向 MDCheckbox 添加功能。我试图设置一个布尔值为 True/False 的 active 参数(我都试过了,但似乎没有任何效果)。我更改了代码的某些部分以方便您使用,但如果您想查看原始源代码,可以查看 here。 (在原始源代码中,MDCheckboxes 在第 143 行。

非常感谢!

问题

on_active 活动的 KivyMD MDCheckbox 未触发事件。

根本原因

动态class规则,<ListItemWithCheckbox@OneLineAvatarIconListItem>:只继承了OneLineAvatarIconListItem,没有继承MDCheckbox。因此,当 MDCheckbox 处于活动状态时,不会触发 on_active 事件,而且事件被放错了位置。

解决方案

  • 添加新的 class 属性,例如msg 来保存不同的文本。
  • 在实例化子项下实施 on_active 事件,MDCheckbox:
  • 将文本分配给实例化子项下的 msgListItemWithCheckbox:

片段

<ListItemWithCheckbox@OneLineAvatarIconListItem>:
    msg: ''
    MyAvatar:
        source: 'src/hdl.jpg'
    MyCheckbox:
        on_active: app.root.printS(root.msg)

...
                        ListItemWithCheckbox:
                            id: ckbx1
                            text: 'Box 1'
                            msg: 'Text 1'


                        ListItemWithCheckbox:
                            id: ckbx2
                            text: 'Box 2'
                            msg: 'Text 2'

                        ListItemWithCheckbox:
                            id: ckbx3
                            text: 'Box 3'
                            msg: 'Text 3'

输出