Kivy - 我无法使用 id 更改 .source

Kivy - I can't change .source with an id

提问人:Leon Kardaš 提问时间:4/21/2021 更新时间:4/22/2021 访问量:95

问:

我想在一个盒子里改变我的图片,我正在尝试在id的帮助下做到这一点。我尝试了很多解决方案,搜索了 3 个多小时,但我无法得到任何正确的东西,所以我将不胜感激。我对Kivy也很陌生。

我试着改变:

self.ids.rec.source = 'download.jpg'

to(正如 Python 所建议的那样 - Kivy:AttributeError:“super”对象在尝试获取 self.ids 时没有属性“__getattr__”)

self.parent.parent.ids

它没有用,只是将我的错误更改为:

 AttributeError: 'NoneType' object has no attribute 'parent'

试图自己摆弄它,但除了将错误更改为另一个错误之外,也无能为力。

这是我的python文件:

from kivy.app import *
from kivy.uix.button import *
from kivy.graphics import *
from kivy.uix.widget import *
from kivy.uix.label import *
from kivy.uix.floatlayout import *
from kivy.uix.boxlayout import *
from kivy.uix.relativelayout import *
from kivy.properties import ListProperty, StringProperty,ObjectProperty
x = []
f = []
#---------------------------------------------------------------------------------
class Picture(FloatLayout):
    def __init__(self, **kwargs):
        super(Picture, self).__init__(**kwargs)
    def change(self,**kwargs):
        y = len(x)
        if y % 2 == 0:
            self.ids.rec.source = 'download.jpg'
            tilesource = 'download.jpg'
            print("aaaa")
        else:
            tilesource = 'images.jpg'
            print("bbbbb")

#---------------------------------------------------------------------------------
class TileWidget(FloatLayout):
    def __init__(self, **kwargs):
        super(TileWidget, self).__init__(**kwargs)
        self.pos = (0, 0)
        self.size = (1,1)
        d = Picture()
        self.add_widget(d)

    def swap(self):
        x.append("0")
        Picture().change()
#---------------------------------------------------------------------------------
class langApp(App):
    def build(self):
        return TileWidget()
#---------------------------------------------------------------------------------

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


And this is my .kv file:

    #:kivy 1.11.1
<TileWidget>:
    FloatLayout:
        pos: 0,0
        size: root.width,root.height
        Button:
            text: 'Last'
            pos_hint: {'x':.25,'y':.1}
            size_hint: .1,.1
        Button:
            text: 'Stop'
            pos_hint: {'x':.45,'y':.1}
            size_hint: .1,.1
        Button:
            on_press: root.swap()
            text: 'Next'
            pos_hint: {'x':.65,'y':.1}
            size_hint: .1,.1
<Picture>:
    pos_hint: {'x':.25,'y':.4}
    canvas:
        Rectangle:
            id: rec
            size: self.size[0]*0.5,self.size[1]*0.5
            pos: self.pos[0],self.pos[1]
            source: "images.jpg"

这是我的完整错误日志:

 Traceback (most recent call last):
   File "kivy\properties.pyx", line 861, in kivy.properties.ObservableDict.__getattr__
 KeyError: 'rec'

 During handling of the above exception, another exception occurred:

 Traceback (most recent call last):
   File "c:/Users/Leon/mobile/main.py", line 45, in <module>
     langApp().run()
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\app.py", line 950, in run
     runTouchApp()
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\base.py", line 582, in runTouchApp
     EventLoop.mainloop()
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\base.py", line 347, in mainloop
     self.idle()
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\base.py", line 391, in idle
     self.dispatch_input()
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\base.py", line 342, in dispatch_input
     post_dispatch_input(*pop(0))
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\base.py", line 248, in post_dispatch_input
     listener.dispatch('on_motion', etype, me)
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\core\window\__init__.py", line 1412, in on_motion
     self.dispatch('on_touch_down', me)
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\core\window\__init__.py", line 1428, in on_touch_down
     if w.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\uix\behaviors\button.py", line 151, in on_touch_down
     self.dispatch('on_press')
   File "kivy\_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
   File "kivy\_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
   File "kivy\_event.pyx", line 1132, in kivy._event.EventObservers._dispatch
   File "C:\Users\Leon\mobile\env\lib\site-packages\kivy\lang\builder.py", line 57, in custom_callback
     exec(__kvlang__.co_value, idmap)
   File "c:\Users\Leon\mobile\lang.kv", line 15, in <module>
     on_press: root.swap()
   File "c:/Users/Leon/mobile/main.py", line 37, in swap
     Picture().change()
   File "c:/Users/Leon/mobile/main.py", line 19, in change
     self.ids.rec.source = 'download.jpg'
   File "kivy\properties.pyx", line 864, in kivy.properties.ObservableDict.__getattr__
 AttributeError: 'super' object has no attribute '__getattr__'
Python Kivy Kivy 语言

评论


答:

0赞 John Anderson 4/22/2021 #1

代码存在两个问题:

方法:swap()

def swap(self):
    x.append("0")
    Picture().change()

正在创建新实例并调用该新实例。这对实际位于 GUI 中的实例没有影响。解决此问题的一种简单方法是保留对 GUI 中实际存在的实例的引用,并在方法中使用该引用:Picturechange()PicturePictureswap()

class TileWidget(FloatLayout):
    def __init__(self, **kwargs):
        super(TileWidget, self).__init__(**kwargs)
        self.pos = (0, 0)
        self.size = (1,1)
        self.d = Picture()
        self.add_widget(self.d)

    def swap(self):
        x.append("0")
        self.d.change()

第二个问题是你不能使用 for canvas 指令,但你可以使用 .因此,您可以将指令放在自己的组中:idsgroupsRectangle

<Picture>:
    pos_hint: {'x':.25,'y':.4}
    canvas:
        Rectangle:
            group: 'rec'  # place this instruction in its own group
            size: self.size[0]*0.5,self.size[1]*0.5
            pos: self.pos[0],self.pos[1]
            source: "images.jpg"

然后你可以用它来修改:groupRectangle

def change(self,**kwargs):
    y = len(x)
    if y % 2 == 0:
        rec = self.canvas.get_group('rec')[0]
        rec.source = 'download.jpg'
        tilesource = 'download.jpg'
        print("aaaa")
    else:
        tilesource = 'images.jpg'
        print("bbbbb")