【问题标题】:AttributeError: 'Screen' object has no attribute 'text' in Python KivyMDAttributeError:“屏幕”对象在 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>

【问题讨论】:

    标签: python-3.x drop-down-menu kivy kivy-language kivymd


    【解决方案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

    【讨论】:

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