【问题标题】:(KivyMD) How to call a function when using 2 kv files/strings?(KivyMD) 使用 2 kv 文件/字符串时如何调用函数?
【发布时间】:2021-10-21 13:27:27
【问题描述】:

我有一个带有按钮的屏幕的 kivymd 应用程序。当您单击此按钮时,屏幕上将出现一个 MDCard。当您单击这个新的 MDCard 时,它将调用一个函数,该函数将在终端上打印一条消息。但是,我无法让这个 MDCard 调用该函数。我收到错误消息:

 AttributeError: 'MDCard' object has no attribute 'option'

MDCard 位于与主 kv 字符串不同的 kv 字符串中。基本上我有两个 kv 字符串。当您按下按钮时,第二个 kv 字符串将作为一个小部件添加到第一个 kv 字符串中。

我认为这是因为第二个 kv 字符串没有作为根的类,但我不知道该怎么做。如何让 MDCard 调用该函数??

MAIN.PY

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
from button_screen import button_screen

MainNav = '''
<ContentNavigationDrawer>:
    ScrollView:
        MDList:
            OneLineListItem:
                text: 'Go to Button Screen'
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "go_to_button_screen"

Screen:
    MDToolbar:
        id: toolbar
        pos_hint: {"top": 1}
        elevation: 10
        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
    MDNavigationLayout:
        x: toolbar.height
        ScreenManager:
            id: screen_manager
            Screen:
                name: "words_nav_item"
            button_screen:
                name: "go_to_button_screen"

        MDNavigationDrawer:
            id: nav_drawer
            ContentNavigationDrawer:
                screen_manager: screen_manager
                nav_drawer: nav_drawer
'''


class ContentNavigationDrawer(BoxLayout):
    screen_manager = ObjectProperty()
    nav_drawer = ObjectProperty()


class main_test(MDApp):
    def build(self):
        self.theme_cls.primary_palette = "Red"
        return Builder.load_string(MainNav)


main_test().run()

按钮屏幕 .PY 文件

from kivy.lang import Builder
from kivymd.uix.screen import MDScreen

button_screen_kv = '''
<button_screen>:
    MDGridLayout:
        cols: 1
        size: root.width, root.height
        spacing: 40
        md_bg_color: [0,0,.1,.1]
        MDGridLayout:
            cols: 1
            size_hint_y: None
            height: 40

        MDGridLayout:
            cols: 1
            Button:
                text: "Click to add card"
                on_release:
                    root.add_card("card 1")
        
        MDGridLayout:
            id: add_card_here_id
            cols: 1

'''

md_card_kv = '''
MDCard:
    orientation: 'vertical'
    size_hint: None, None
    size: "360dp", "120dp"
    ripple_behavior: True
    on_release:
        root.option("MDCard was clicked")
    MDLabel:
        id: LabelTextID
        text: "this is an MDCard"
        halign: 'center'
'''


class button_screen(MDScreen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Builder.load_string(button_screen_kv)
        self.md_card_widget = Builder.load_string(md_card_kv)

    def option(self, string):
        print(f"{string}")

    def add_card(self, *args):

        self.ids.add_card_here_id.add_widget(self.md_card_widget)

【问题讨论】:

    标签: python python-3.x kivy kivy-language kivymd


    【解决方案1】:

    我想出了以下可行的方法,但是我还是编程新手,所以我不知道这是否是一个稳定的解决方案。请在那里告诉我

    解决方案:

    • 我在buttonscreen.py 中添加了另一个类class user_card(MDGridLayout) 并将kv 字符串放在那里。
    • 我将该类设置为 kv 字符串中的根小部件
    • init 方法中,我放置了一个函数,该函数将返回 kv 字符串 return self.user_card_string
    • 然后我将该类作为参数添加到 add_widget 中,并将col 作为参数传递:self.ids.add_card_here_id.add_widget(user_card(cols=1))

    一切正常,但我以前从未使用过两个类。所以我不确定这是否会成为未来的问题。

    button_screen.py:

    from kivy.lang import Builder
    from kivymd.uix.gridlayout import MDGridLayout
    from kivymd.uix.screen import MDScreen
    
    button_screen_kv = '''
    <button_screen>:
        MDGridLayout:
            cols: 1
            size: root.width, root.height
            spacing: 40
            md_bg_color: [0,0,.1,.1]
            MDGridLayout:
                cols: 1
                size_hint_y: None
                height: 40
    
            MDGridLayout:
                cols: 1
                Button:
                    text: "Click to add card"
                    on_release:
                        root.add_card("card 1")
            
            MDGridLayout:
                id: add_card_here_id
                cols: 1
    
    '''
    
    md_card_kv = '''
    <user_card>:
        MDGridLayout:
            cols: 1
            MDCard:
                orientation: 'vertical'
                size_hint: None, None
                size: "360dp", "120dp"
                ripple_behavior: True
                on_release:
                    root.option()
                MDLabel:
                    id: LabelTextID
                    text: "this is an MDCard"
                    halign: 'center'
    '''
    
    
    class user_card(MDGridLayout):
        user_card_string = Builder.load_string(md_card_kv)
    
        def __init__(self, *args, **kwargs):
            super().__init__(**kwargs)
            self.load_card()
    
        def option(self, *args):
            print("MDCard was clicked")
    
        def load_card(self):
            return self.user_card_string
    
    
    class button_screen(MDScreen):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            Builder.load_string(button_screen_kv)
    
        def add_card(self, *args):
            self.ids.add_card_here_id.add_widget(user_card(cols=1))
    

    【讨论】:

      猜你喜欢
      • 2021-04-14
      • 2021-10-05
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-22
      • 2023-03-18
      相关资源
      最近更新 更多