gra*_*sch 5 python kivy kivy-language
我为一种android锁定的东西编写了一个代码,每当我尝试使用id获取特定的ClickableImage时,它会引发以下错误:
AttributeError: 'super' object has no attribute '__getattr__'
Run Code Online (Sandbox Code Playgroud)
我花了好几个小时试图寻找这个问题的解决方案,我看着其他人有同样的问题,人们告诉他们改变构建器的站点,因为需要先调用它来获取ids属性或其他东西像那样,但每次我移动构建器时,都会引发错误"class not defined".有线索吗?
这是我的代码:
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()
Run Code Online (Sandbox Code Playgroud)
这是我的.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:
Run Code Online (Sandbox Code Playgroud)
我们来看看输出:
'super' object has no attribute '__getattr__'
Run Code Online (Sandbox Code Playgroud)
在kv语言id中以特殊方式设置(现在最多为1.9.2),其值不是字符串,因为它不是随意变量.您无法访问它<widget>.id.
我会说它类似于canvas,它不是一个小部件,但它可能看起来像那样(这就是为什么我对你的代码感到困惑:P).你已经注意到something: <some object>就像Python一样something = <object>,而且(至少我认为)的重点是id不是一个字符串(有些是奇数).如果id是一个字符串,可能需要一个检查来以某种方式从偶然分配值中排除它.也许是因为性能或简单.
因此,假设id是未来关键字的关键字.实际上,它是,因为分配给的字符id将成为一个字符串键,其值为WeakProxy的对象,而WeakProxy指向的对象.或者更好地说:
id: value
Run Code Online (Sandbox Code Playgroud)
变
<some_root_widget>.ids[str(value)] = weakref.proxy(value)
Run Code Online (Sandbox Code Playgroud)
哪里value成为一个对象(什么print(self)会返回)
我怀疑(不确定)如果你使用字符串作为值id,你最终将使用指向字符串的weakref/WeakProxy.我使用这个词,point因为它提醒我指针,不要与C指针混淆.
现在,如果再看一下输出:
super 使您可以访问从中继承的类
print('string id'.__getattr__)会给你相同的错误,但'super'用真实值代替,因为嗯......它没有__getattr__
因此,如果您指定一个字符串值id,您将陷入这种情况:
<some_root_widget>.ids[str('value')] = weakref.proxy('value') # + little bit of magic
Run Code Online (Sandbox Code Playgroud)
虽然str('value')不一定是错误的,但默认情况下,您无法为字符串创建weakref.proxy.我不确定Kivy如何使用WeakProxies来处理这个问题,但是如果你指定了一个字符串id,大致这就是你得到的.
(如果我错了,请纠正我)