AttributeError: 'Screen' object has no attribute 'text' in Python KivyMD

AttributeError: 'Screen' object has no attribute 'text' in Python KivyMD

Python 3.9.0

KivyMD 0.104.2.dev0

预期进球

所以我想根据芯片的文本是否存在于名为 list1 的列表中来清除一些 MDChips,但这样做会出现以下错误

问题

当我尝试使用 def clear(self) 函数访问 Widget 树时,我不断收到错误消息,但我不断收到上述错误消息

我发现在下面的 kv 字符串中使用 Screen : 会出现上述错误(在标题中提到)。

button = '''
Screen:
    MDRaisedButton:
        id: button_id
        text: "PRESS ME"
        pos_hint: {"center_x": .35, "center_y": .8}
        on_release: app.drop.open()
'''

但是,如果我删除 Screen :,那么出于某种原因,MDDropDownMenu 小部件在使用 open() 调用时会抛出以下错误:

AttributeError: 'super' object has no attribute '__ getattr __'

代码

from kivy.lang import Builder
from kivymd.uix.screen import Screen
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivymd.uix.chip import MDChip
from kivymd.uix.floatlayout import FloatLayout

button = '''
Screen:
    MDRaisedButton:
        id: button_id
        text: "PRESS ME"
        pos_hint: {"center_x": .35, "center_y": .8}
        on_release: app.drop.open()
'''

button1 = '''
Screen:
    MDRaisedButton:
        id: button1_id
        text: "PRESS ME 2"
        pos_hint: {"center_x": .5, "center_y": .8}
        on_release: app.clear()
'''

list1 = (['Item 1','Item 2','Item 3'], ['Item 4', 'Item 5', 'Item 6'])
class Test(MDApp):
    def build(self):
        self.screen = Screen()
        self.btn = Builder.load_string(button)
        self.btn1 = Builder.load_string(button1)

        self.screen.add_widget(self.btn1)
        self.screen.add_widget(self.btn)


        self.drop = MDDropdownMenu(
            caller = self.btn.ids.button_id,
            items = [{'text':'Show Chips'}],
            width_mult = 4,
        )
        self.drop.bind(on_release=self.testing)

        return self.screen
    
    def testing(self, menu, menu_item):
        objects = {0.2 : "Item 1", 0.5 : "Item 2", 0.8 : "Item 3"}
        for pos, item in objects.items():
            self.chip = MDChip(
                text = item,
                check = True,
                pos_hint = {"center_x":pos, "center_y":0.4},
                
            )
            self.screen.add_widget(self.chip)

    def clear(self):
        for child in self.root.children[:]:
            if child.text in list1[0]:
                self.root.remove_widget(child)

Test().run()

错误

Traceback (most recent call last):
   File "e:\Projects\Workout Planner\Planner v_1\My_Project\Test\test.py", line 61, in <module>
     Test().run()
   File "C:\Users\Mocha\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\app.py", line 949, in run
     self._run_prepare()
   File "C:\Users\Mocha\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\app.py", line 919, in _run_prepare
     root = self.build()
   File "e:\Projects\Workout Planner\Planner v_1\My_Project\Test\test.py", line 37, in build
     caller = self.btn.ids.button_id,
   File "kivy\properties.pyx", line 864, in kivy.properties.ObservableDict.__getattr__
 AttributeError: 'super' object has no attribute '__getattr__'
PS E:\Projects\Workout Planner\Planner v_1\My_Project>

虽然我不知道为什么它在我之前发布的代码中不起作用的正确原因,但我已经找到了问题的修复方法

解决方案:

您必须构建另一个继承自 Screen 的 class。 然后 enter/copy 您希望在这个新的 Class.

应用程序中拥有的所有内容

并且在继承自 MDApp 的 Class 中您可以指定您想要的主题,并且 return 继承自 Screen[=17] 的 Class =]

此外,在将所有小部件转移到继承自 Screen 的 Class 后,确保将此 class 称为 root 而不是 app您可以将功能绑定到按钮或用它做其他事情。

解决方案代码:

from kivy.lang import Builder
from kivymd.uix.screen import Screen
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivymd.uix.chip import MDChip
from kivymd.uix.floatlayout import FloatLayout

Builder.load_string(
    """
<BuildApp>:

    MDRaisedButton:
        id: button_id
        text: "PRESS ME"
        pos_hint: {"center_x": .35, "center_y": .8}
        on_release: root.drop.open()

    MDRaisedButton:
        id: button1_id
        text: "PRESS ME 2"
        pos_hint: {"center_x": .5, "center_y": .8}
        on_release: root.clear()
        
    """
)#reference should be as root.function_name(),


list1 = (['Item 1','Item 2','Item 3'], ['Item 4', 'Item 5', 'Item 6'])

class BuildApp(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.drop = MDDropdownMenu(
            caller = self.ids.button_id,   #use self.id.id_name
            items = [{'text':'Show Chips'}],
            width_mult = 4,
        )
        self.drop.bind(on_release=self.show_chips)
    
    def show_chips(self, menu, menu_item):
        objects = {0.2 : "Item 1", 0.5 : "Item 2", 0.8 : "Item 3"}
        for pos, item in objects.items():
            self.chip = MDChip(
                text = item,
                check = True,
                pos_hint = {"center_x":pos, "center_y":0.4},
                
            )
            self.add_widget(self.chip)

    def clear(self):
        for child in self.children[:]:
            if child.text in list1[0]:
                self.remove_widget(child)

class Test(MDApp):
    def build(self):
        return BuildApp()

    
    

Test().run()

Reference