为什么MDCard无法在KivyMD中添加on_touch_down?
Why MDCard not able to add on_touch_down in 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'
"""
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)
我已经实现了以下。底页中有两个按钮。单击第一个按钮时,它会从主屏幕转到第一个屏幕。在第一个屏幕上,点击右上角的按钮将创建 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'
"""
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)