在Python/KivyMD。带有复选框的 MDDialog,如果其中一个复选框被选中,"CONFIRM" 按钮不起作用

In Python/KivyMD. MDDialog with check boxes where "CONFIRM" button doesn't work if one of check boxes are checked

我用 python 3.9.5kivy 2.0.0rc4kivymd 0.104.2 做了一个游戏。我做了MDDialog。其中有复选框。如果选中 none 个,我想禁用“确认”按钮。如果选中其中一个,我想启用“确认”按钮。当 none 未选中时,我已设法禁用,但如果我选中其中一个,按钮仍处于禁用状态。这是我的 python 代码:

class ItemConfirm(OneLineAvatarIconListItem):
    divider = None
    dialog = None

    def show_confirmation_dialog(self, *args):

        self.dialog = MDDialog(
            title="Score Limit",
            type="confirmation",
            auto_dismiss=False,
            items=[
                ItemConfirm(text="30"),
                ItemConfirm(text="40"),
                ItemConfirm(text="50"),
                ItemConfirm(text="60"),
            ],
            buttons=[
                MDFlatButton(
                    text="CONFIRM", text_color=(1, 0, 0, 1), on_release=self.score_limit, disabled=True if self.ids.check.active == False else False
                ),
            ]
        )
        self.dialog.open()

    def score_limit(self, *args, **kwargs):
        self.dialog.dismiss()

这是我的 kivy 代码:

<ItemConfirm>

    CheckboxLeftWidget:
        id: check
        group: "check"

您可以通过定义一个 BooleanProperty 来反映 confirm 按钮是否处于活动状态,从而使您的 confirm 按钮成为 enabled/disabled。最简单的方法是利用 kivy lang 创建的自动绑定。为了做到这一点,我不得不基本上重写你的代码。对于重写,我深表歉意,但这是对您的代码的修订,可以满足您的要求:

from kivy.lang import Builder
from kivy.properties import BooleanProperty
from kivy.uix.button import Button
from kivymd.app import MDApp
from kivymd.uix.dialog import MDDialog
from kivymd.uix.list import OneLineAvatarIconListItem
from kivymd.uix.selectioncontrol import MDCheckbox

kv = '''
#:import Factory kivy.factory.Factory
<ItemConfirm>
    divider: None
    CheckboxRightWidget:
        id: check
        score: root.text  # makes the score text available from the Checkbox
        group: "check"
        on_active: app.check_active(self.group)  # update app.active
        
<ConfirmButton@MDFlatButton>:
    text: 'CONFIRM'
    disabled: not app.active  #  disabled when app.active is False
    on_release: app.score_limit()
    
<ConfirmDialog>:
    title: "Score Limit"
    type: "confirmation"
    auto_dismiss: False
    items: [ Factory.ItemConfirm(text="30"), Factory.ItemConfirm(text="40"), Factory.ItemConfirm(text="50"), Factory.ItemConfirm(text="60") ]
    buttons: [ Factory.ConfirmButton() ]
'''


class ItemConfirm(OneLineAvatarIconListItem):
    pass


class ConfirmDialog(MDDialog):
    pass


class TestApp(MDApp):
    active = BooleanProperty(False)  # keeps track if any Checkbox is active

    def build(self):
        Builder.load_string(kv)
        return Button(text='Do It', on_release=self.show_confirmation_dialog)

    def show_confirmation_dialog(self, *args):
        self.dialog = ConfirmDialog()
        self.dialog.open()

    def score_limit(self, *args, **kwargs):
        print('score limit:', self.check_active('check'))
        self.dialog.dismiss()
        self.dialog = None  # required to eliminate current group of Checkboxes
        self.active = False

    def check_active(self, group):  # update app.active and return current score limit (or None)
        for cb in MDCheckbox.get_widgets(group):
            if cb.active:
                self.active = True
                return cb.score
        self.active = False
        return None


TestApp().run()

由于 MDDialog 必须构建的方式(buttons 必须是 Button 对象的列表),我不知道有什么方法可以分配 id 那些 Buttons.