AttributeError:“屏幕”对象在 Python KivyMD 中没有属性“文本”

Posted

技术标签:

【中文标题】AttributeError:“屏幕”对象在 Python KivyMD 中没有属性“文本”【英文标题】:AttributeError: 'Screen' object has no attribute 'text' in Python KivyMD 【发布时间】:2021-06-22 07:34:49 【问题描述】:

Python 3.9.0

KivyMD 0.104.2.dev0

预期目标

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

问题

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

我发现在下面的 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 :,那么由于某种原因,使用 open() 调用 MDDropDownMenu 小部件时会引发以下错误:

AttributeError: 'super' 对象没有属性 '__ 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>

【问题讨论】:

【参考方案1】:

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

解决方案:

您必须构建另一个继承自Screen 的类。 然后在这个新类中输入/复制您希望在应用程序中拥有的所有内容。

在继承自 MDApp 的 Class 中,您可以指定您想要的主题并返回继承自 Screen 的 Class

此外,在将所有小部件转移到继承自 Screen 的类之后,请确保将此类称为 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

【讨论】:

以上是关于AttributeError:“屏幕”对象在 Python KivyMD 中没有属性“文本”的主要内容,如果未能解决你的问题,请参考以下文章

错误“AttributeError:'Py4JError'对象没有属性'message'构建DecisionTreeModel

AttributeError:“屏幕”对象在 Python KivyMD 中没有属性“文本”

python manage.py runserver:AttributeError:“模块”对象没有属性“选择”

kivymd 中的屏幕没有改变,显示“AttributeError:‘NoneType’对象没有属性‘transition’”

AttributeError:“模块”对象没有属性

面向对象时遇见的属性错误(AttributeError)