AttributeError: 'Screen' 对象在 Python KivyMD 中没有属性'text'



Python 3.9.0

KivyMD 0.104.2.dev0

预期目标

因此,我想根据芯片的文本是否存在于名为list1的列表中来清除一些MDChip,但这样做会产生以下错误

问题

当我尝试使用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()调用时会抛出以下错误:

属性错误:"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:ProjectsWorkout PlannerPlanner v_1My_ProjectTesttest.py", line 61, in <module>
Test().run()
File "C:UsersMochaAppDataLocalProgramsPythonPython39libsite-packageskivyapp.py", line 949, in run
self._run_prepare()
File "C:UsersMochaAppDataLocalProgramsPythonPython39libsite-packageskivyapp.py", line 919, in _run_prepare
root = self.build()
File "e:ProjectsWorkout PlannerPlanner v_1My_ProjectTesttest.py", line 37, in build
caller = self.btn.ids.button_id,
File "kivyproperties.pyx", line 864, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
PS E:ProjectsWorkout PlannerPlanner v_1My_Project>

我已经找到了这个问题的解决方案,尽管我不知道它在我之前发布的代码中不起作用的正确原因

解决方案:

您必须构建另一个继承自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()

参考

最新更新