7

我为一种 android lock 编写了一个代码,每当我尝试使用 id 获取特定的 ClickableImage 时,它​​都会引发以下错误:

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

我花了几个小时试图寻找这个问题的解决方案,我查看了其他有同样问题的人,人们告诉他们更改构建器的站点,因为需要首先调用它来获取 ids 属性或其他东西就像那样,但是每次我移动构建器时,都会引发错误“类未定义”。有什么线索吗?

这是我的代码:

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:
4

2 回答 2

9

让我们看看输出:

'super' object has no attribute '__getattr__'

在 kv 语言id中以特殊的方式设置(现在到 1.9.2),它的值不是一个字符串,因为它不是一个随意的变量。您无法使用<widget>.id.

我会说它类似于canvas,它不是一个小部件,但它可能看起来像那样(这就是我对你的代码感到困惑的原因:P)。您已经注意到something: <some object>它就像 Python 的something = <object>那样(至少我认为)是id' 值的全部意义不是字符串(这对某些人来说很奇怪)。如果id是一个字符串,则可能需要进行检查以某种方式将其排除在随意分配值之外。也许是因为性能或只是简单。

因此,假设id是未来关键字的关键字。实际上是这样,因为分配给的字符id会变成一个字符串键,其值为从WeakProxy获取的object,指向WeakProxy指向的对象。或者更好地说:

id: value

变成

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

wherevalue成为一个对象(什么print(self)会返回)

我怀疑(不确定)如果您使用字符串作为 的值id,您最终会得到指向字符串的弱引用/弱代理。我使用这个词point是因为它提醒我指针,不要与 C 指针混淆。

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

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

  • print('string id'.__getattr__)会给你同样的错误,但是'super'用真正的价值代替,因为嗯......它没有__getattr__

因此,如果您将字符串值分配给id,您将遇到这种情况:

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

虽然str('value')不一定是错的,但默认情况下您不能为字符串创建 weakref.proxy。我不确定 Kivy 如何使用 Wea​​kProxies 处理这个问题,但如果你将字符串分配给id,大致就是你得到的。

(如果我错了请纠正我)

于 2016-08-25T18:35:45.767 回答
0

定义 id 时不要使用引号。

id: uno

代替

id: 'uno'
于 2022-01-17T10:18:28.217 回答