为什么MDCard无法在KivyMD中添加on_touch_down?

时间:2020-09-17 17:47:15

标签: python kivy kivymd

我实现了以下内容。底部有两个按钮。当单击第一个按钮时,它将从主屏幕转到第一个屏幕。在第一个屏幕上,单击右上角的按钮将创建10张卡。

但是当尝试添加on_touch_down时,它就会崩溃。我添加了toast print,还添加了一些功能,但是没有任何作用。

那么这将是解决方案?谢谢

main.py 我已评论on_touch_down = toast('clicked')。没有它,它就可以工作,但是当取消注释时,应用程序就会崩溃。如何实现呢?这样卡就可以点击了。

from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
from kivymd.toast import toast
from kivymd.uix.bottomsheet import MDGridBottomSheet
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.card import MDCard
from kivymd.uix.label import MDLabel
from build_string import helper_string

class MainScreen(Screen):
    pass

class FirstScreen(Screen):
    pass


class SecondScreen(Screen):
    pass


class MainApp(MDApp):

    def build(self):
        self.dialog = ""

        self.sm = Builder.load_string(helper_string)
        return self.sm

    def callback_for_main_menu_items(self, *args):
        toast(args[0])
        if args[0] == 'First':
            self.sm.current = "first_screen"
        if args[0] == 'Home':
            self.sm.current = "main_screen"

    def show_main_grid_bottom_sheet(self):
        self.bottom_sheet_main_menu = MDGridBottomSheet()

        data = {
            "First": "page-first",
            "Home": "home",
        }
        for item in data.items():
            self.bottom_sheet_main_menu.add_item(
                item[0],
                lambda x, y=item[0]: self.callback_for_main_menu_items(y),
                icon_src=item[1],
            )
        self.bottom_sheet_main_menu.open()

    def print_test(self):
        print("test")
        self.show_alert_dialog()

    def show_alert_dialog(self):
        if not self.dialog:
            self.dialog = MDDialog(
                title="Dialog",
                size_hint= [0.9, None],
                buttons=[
                    MDFlatButton(
                        text="CANCEL", text_color=self.theme_cls.primary_color
                    ),
                    MDFlatButton(
                        text="DISCARD", text_color=self.theme_cls.primary_color
                    ),
                ],
            )
        self.dialog.open()

    def make_card(self):

        for i in range(10):
            card = MDCard(
                orientation="vertical",
                padding="8dp",
                ripple_behavior=True,
                size_hint=[1, None],
                #on_touch_down = toast('clicked')
            )

            label_link = MDLabel(text="Card" + str(i))
            label_link.font_style = "Caption"

            label_header = MDLabel(text="Title" + str(i))
            label_header.size_hint = [1, 1]

            card.add_widget(label_link)
            card.add_widget(label_header)

            self.sm.ids.first_screen_id.ids.first_screen_box_layout.add_widget(card)

if __name__ == '__main__':
    MainApp().run()

build_string.py

helper_string = """
<MenuButton@MDIconButton>:
    icon: "menu"
    theme_text_color: "Custom"
    text_color: 1,0,0,1
    halign: 'bottom'  
    on_press: app.show_main_grid_bottom_sheet()

<TButton@MDIconButton>:
    icon: "menu"
    theme_text_color: "Custom"
    text_color: 1,0,0,1
    halign: 'center'  

<TitleText@MDLabel>
    pos_hint: {"center_y": .95}
    halign: "center"
    theme_text_color: "Custom"
    text_color: 0, 0, 1, 1
    font_style: "Subtitle1"

ScreenManager:
    id: screen_manager
    MainScreen:
    FirstScreen:
        id: first_screen_id
    SecondScreen:

<MainScreen>:
    name: 'main_screen'
    BoxLayout:
        orientation: "vertical"
        spacing: "5dp"

        MDToolbar:
            id: toolbar
            pos_hint: {'bottom': 1}
            #right_action_items: [["dots-vertical", lambda x: app.show_main_grid_bottom_sheet()]]
            left_action_items: [["menu", lambda x: app.show_main_grid_bottom_sheet()]]   

<FirstScreen>:
    name: 'first_screen'
    BoxLayout:
        id: first_screen_box
        orientation: "vertical"
        spacing: "5dp"

        MDToolbar:
            id: toolbar
            title: "First Screen"
            elevation: 5
            pos_hint: {'top': 1}
            right_action_items: [["refresh", lambda x: app.make_card()]]

        ScrollView:                
            MDBoxLayout:
                id: first_screen_box_layout
                orientation: 'vertical'
                adaptive_height: True
                padding: dp(15)
                spacing: dp(5) 

        MDToolbar:
            id: toolbar
            pos_hint: {'bottom': 1}
            #right_action_items: [["dots-vertical", lambda x: app.show_main_grid_bottom_sheet()]]
            left_action_items: [["menu", lambda x: app.show_main_grid_bottom_sheet()]]   

<SecondScreen>:
    name: 'second_screen'
"""

1 个答案:

答案 0 :(得分:1)

on_touch_down是可以绑定的事件,不是可以设置的MDCard的属性。因此,您可以像这样进行绑定:

def make_card(self):
    for i in range(10):
        card = MDCard(
            orientation="vertical",
            padding="8dp",
            ripple_behavior=True,
            size_hint=[1, None],
            #on_touch_down = toast('clicked')
        )
        card.bind(on_touch_down=self.clicked)  # set binding

        label_link = MDLabel(text="Card" + str(i))
        label_link.font_style = "Caption"

        label_header = MDLabel(text="Title" + str(i))
        label_header.size_hint = [1, 1]

        card.add_widget(label_link)
        card.add_widget(label_header)

        self.sm.ids.first_screen_id.ids.first_screen_box_layout.add_widget(card)

# method called by binding
def clicked(self, card, touch):
    if card.collide_point(*touch.pos):
        print('clicked on', card.children[0].text)