Python-Kivy:AttributeError:“超级"对象在尝试获取self.ids时没有属性"__getattr__" [英] Python - Kivy: AttributeError: 'super' object has no attribute '__getattr__' when trying to get self.ids

查看:448
本文介绍了Python-Kivy:AttributeError:“超级"对象在尝试获取self.ids时没有属性"__getattr__"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我尝试使用id获取特定的ClickableImage时,我都会为一种Android锁事物编写代码,这会引发以下错误:

I wrote a code for a kind of android lock thing, whenever I try to get an specific ClickableImage using the id it raises the following error:

AttributeError: 'super' object has no attribute '__getattr__'

我花了数小时试图寻找解决此问题的方法,我寻找了其他遇到相同问题的人,人们告诉他们更改构建器的站点,因为需要先调用它以获取ID.属性或类似属性,但是每次我移动构建器时,都会引发错误类未定义".有任何线索吗?

I've spent hours trying to look for a solution for this problem, I looked other people with the same issue, and people told them to change the site of the builder, because it needed to be called first to get the ids attribute or something like that, but everytime I move the builder, it raises the error "class not defined". Any clues?

这是我的代码:

from kivy.app import App
from kivy.config import Config
from kivy.lang import Builder
from kivy.graphics import Line
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import ButtonBehavior

#Variables
cords = ()
bld = Builder.load_file('conf.kv')

class Manager(ScreenManager): pass
class Principal(Screen): pass

class ClickableImage(ButtonBehavior, Image):
    def on_press(self):
        self.source = 'button_press.png'

    def on_release(self):
        self.source = 'button.png'
        self.ids.uno.source = 'button_press.png'

class canva(Widget):
    def on_touch_down(self, touch):
        global cords
        with self.canvas:
            touch.ud['line'] = Line(points=(touch.x, touch.y), width=1.5)
        cords = (touch.x, touch.y)

    def on_touch_move(self,touch):
        global cords
         touch.ud['line'].points = cords + (touch.x, touch.y)

    def on_touch_up(self,touch):
        self.canvas.clear()

class Api(App):    
    def build(self):
        return bld

if __name__ == '__main__':
    Api().run()

这是我的.kv文件:

# conf to file:  test.py

<Manager>:
    Principal:

<Principal>:
    GridLayout:
        size_hint_x: 0.5
        size_hint_y: 0.6
        width: self.minimum_width
        cols: 3
        ClickableImage:
            id: 'uno'
            size: 10,10
            source: 'button.png'
            allow_strech: True
        ClickableImage:
            id: 'dos'
            size: 30,30
            source: 'button.png'
            allow_strech: True
    canva:

推荐答案

让我们看一下输出:

'super' object has no attribute '__getattr__'

以kv语言id进行特殊设置(现在最多1.9.2),它的值不是字符串,因为它不是临时变量.您无法使用<widget>.id来访问它.

In kv language id is set in a special way(up to 1.9.2 now), its value is not a string, because it's not a casual variable. You can't access it with <widget>.id.

我想说它与canvas类似,它不是小部件,但看起来可能像这样(这就是为什么我对您的代码:P感到困惑).您已经注意到something: <some object>就像Python的something = <object>一样,这(至少是我认为的)是id的值的全部不是字符串(有些奇怪).如果id是字符串,则可能需要检查以某种方式将其从临时分配值中排除.也许是因为性能或简单性.

I'd say it's similar to canvas, which is not a widget, yet it may look like that(which is why I was confused by your code :P). You've already noticed something: <some object> is like Python's something = <object> and that's (at least what I think) is the whole point of id's value not being a string(which to some is odd). If id was a string, there'd probably be needed a check to exclude it somehow from casual assigning values. Maybe it's because of performance or just simplicity.

因此,假设id是将来关键字的关键字.实际上,是因为分配给id的字符将成为具有从WeakProxy获得的对象值的字符串键,因此指向WeakProxy指向的对象.或者说更好:

Therefore let's say id is a keyword for a future keyword. In fact, it is, because the characters assigned to id will become a string key with a value of object got from WeakProxy, to the object WeakProxy points to. Or better said:

id: value

成为

<some_root_widget>.ids[str(value)] = weakref.proxy(value)

其中value成为对象(print(self)会返回什么)

where value becomes an object(what print(self) would return)

我怀疑(不确定)如果将字符串用作id的值,则最终会得到 weakref / WeakProxy 指向一个字符串.我使用point这个词来提醒我指针,不要与C指针混淆.

I suspect(not sure) that if you use string as the value for id, you'll end up with weakref / WeakProxy pointing to a string. I use the word point as it reminds me pointers, don't get confused with C pointers.

现在,如果您再次查看输出:

Now if you look again at the output:

  • super使您可以访问从其继承的类

  • super gives you an access to a class you inherit from

print('string id'.__getattr__)会给您同样的错误,但是'super'会替换为实际值,因为...它没有__getattr__

print('string id'.__getattr__) will give you the same error, but 'super' is substituted with the real value, because well... it doesn't have __getattr__

因此,如果id分配 string 值,则会遇到这种情况:

Therefore if you assign a string value to id, you'll get into this situation:

<some_root_widget>.ids[str('value')] = weakref.proxy('value')  # + little bit of magic

尽管str('value')不一定是错误的,但是默认情况下您不能为字符串创建weakref.proxy.我不确定Kivy如何使用WeakProxies处理此问题,但是如果您将字符串分配给id,大致就是您所得到的.

Although str('value') isn't necessarily wrong, by default you can't create weakref.proxy for a string. I'm not sure how Kivy handles this with WeakProxies, but if you assign a string to id, roughly this is what you get.

(如果我错了,请纠正我)

(Please correct me if I'm wrong)

这篇关于Python-Kivy:AttributeError:“超级"对象在尝试获取self.ids时没有属性"__getattr__"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆