python - Kivy AttributeError:“超级”对象没有属性“__getattr__”
问题描述
我有以下问题:我想要一个显示从我的数据库中获取的记录列表的屏幕。此列表应允许用户单击条目,从而切换到“结果”屏幕,该屏幕显示该条目的所有详细信息。
我的browseButton
主屏幕应该切换到BrowseWindow
屏幕,同时在其中构建一个与获取的数据库条目相对应的按钮列表(这就是makeList
函数所做的,通过调用 WMan().dbFetch()) .
到此为止。现在,我想将 on_release 事件绑定到这些按钮,以便单击它们将当前屏幕切换到ResultWindow
并在那里打印输出(这是由 WMan().printRecipe() 执行的)。但是,这会触发错误:
self.ids.result.ids.title.text = recipeName
File "kivy\properties.pyx", line 863, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
我希望我能够足够清楚地解释我的问题。这是我的kv文件:
WMan:
MainWindow:
BrowseWindow:
ResultWindow:
id: result
<MainWindow>:
name: 'main'
browseButton: browseButton
BoxLayout:
Button:
text: 'browse'
on_release:
app.root.current = 'browse'
app.root.current_screen.makeList()
Button:
id: browseButton
text: 'result'
on_release:
app.root.current = 'result'
<BrowseWindow>:
name: 'browse'
on_enter: root.bindList()
browseList: browseList
BoxLayout:
id: browseList
orientation: 'vertical'
size_hint: .9, None
pos_hint: {"x": .05, "top": .8}
#height: self.minimum_height
<ResultWindow>:
name: 'result'
on_enter: app.root.printRecipe('test')
Label:
id: title
pos_hint: {"x":0.05, "top": .9}
size_hint: (.9, None)
height: self.texture_size[0]
ScrollView:
id: scroll
size_hint: (.9, .75)
pos_hint: {"x": 0.05, "top": .75}
StackLayout:
size_hint: .9, None
orientation: 'lr-tb'
spacing: 0, 2
height: self.minimum_height
Label:
text: "Ingredients:"
size_hint: 1, None
#text_size: self.size
#halign: 'left'
height: '30sp'
BoxLayout:
id: ingredientsBox
orientation: 'vertical'
size_hint: 1, None
height: self.minimum_height
py脚本:
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
class MainWindow(Screen):
pass
class BrowseWindow(Screen):
def makeList(self):
recipesList = WMan().dbFetch()
for i in recipesList:
self.browseList.add_widget(
Button(
text=i,
height='30sp'))
return self.browseList
def bindList(self):
for child in self.browseList.children:
print(child.text)
child.bind(on_release = self.listBindings(child))
def listBindings(self, i):
self.manager.current = 'result'
WMan().printRecipe(i.text)
class ResultWindow(Screen):
pass
class WMan(ScreenManager):
def dbFetch(self):
recipesList = ['Recipe1', 'Recipe2', 'Recipe3', 'Recipe4']
return recipesList
def searchRecipe(self, nameInput):
recipeName = nameInput
ingsList = ['Lorem', 'Ipsum', 'Dolor']
steps = "Sed at tortor condimentum, congue nibh sit amet, ornare ligula. "
return recipeName, ingsList, steps
def printRecipe(self, nameInput):
recipeName, ingsList, steps = self.searchRecipe(nameInput)
self.ids.result.ids.title.text = recipeName
for i in range(0, len(ingsList)):
self.current_screen.ids.ingredientsBox.add_widget(
Label(
text=ingsList[i]))
kv = Builder.load_file("test.kv")
class TestApp(App):
def build(self):
return kv
if __name__ == "__main__":
TestApp().run()
解决方案
问题是,您使用的任何地方WMan()
都在创建一个WMan
与 GUI 中的内容无关的新实例。并且由于在显示ids
时分配,因此您的实例中没有未显示的。WMan
ids
WMan
您可以通过替换WMan()
为App.get_running_app().root
到处来解决此问题。这为您提供了对根Widget
的引用App
,WMan
在您的情况下。
推荐阅读
- android - 如何将车速表从特定位置统一旋转到另一个位置?
- css - css:before :将多行文本与图像对齐
- sql - 2 个存储过程结果集的合并应该在数据库端还是 API 端完成?
- c# - 以编程方式触发事件 C#
- ios - 我如何将其转换为 Alamofire 参数?
- git - 使用 git (?) 向客户端分发更新
- python-3.x - 在 Anaconda3 中安装 Pillow 后,Python 3 找不到它
- angular - 在继续使用 Angular 之前等待方法完成
- kotlin - Kotlin 对 hashmap 进行降序排序
- git-log - 德威备忘单:如何重现“git log”?