¿Cómo resolver el error de “nombre de propiedad no válido” para hacer que el selector de archivos con kivy?

Soy nuevo en Kivy y estoy tratando de construir una aplicación en la que tengo tres tabs: una para cargar la imagen, otra para mostrar la imagen y una versión en escala de grises una al lado de la otra, y finalmente, una pestaña para solo mostrar la imagen en escala de grises.

Obtuve lo siguiente en este enlace y espero usar esto para Python 3, pero repetidamente he recibido el error a continuación.

Nombre de propiedad inválido

Este es el código que estoy usando actualmente:

import kivy; from kivy.app import App from kivy.uix.tabbedpanel import TabbedPanel from kivy.properties import ObjectProperty from kivy.lang import Builder from PIL import* Builder.load_string(""" : manager:manager img:img img3:img3 img4:img4 lab:lab do_default_tab:False ScreenManager: id:manager Screen: id:sc1 name:'Load img' FileChooserIconView canvas.before: Color: rgb:0.5, 0.4, 0.5 Rectangle: pos:self.pos size: self.size on_selection:root.select_to(*args) Screen: id:sc2 name:'Image' FloatLayout: Button: id:lab pos_hint:{"right": 0.55, 'top': 1} size_hint:.15,0.1 RelativeLayout: Image: id:img on_touch_down:str('Relative:{}'.format(args[1].pos)) post_hint:{"left": 1, 'bottom': 1} size_hint:0.5, 1 allow_strech:True RelativeLayout: Image: id:img3 post_hint:{"right": 1, 'bottom': 1} size_hint:0.5, 1 allow_strech = True Screen: id:sc3 name:'Image_' FloatLayout: Image: id:img4 keep_data:True post:self.pos size: self.size TabbedPanelHeader: text.sc1.name background_color: 1,0,0,1 screen:sc1.name TabbedPanelHeader: text:sc2.name background_color: 1,1,0,1 screen:sc2.name TabbedPanelHeader: text:sc3.name background_color: 1,0,1,1 screen:sc3.name """) class RootWidget(TabbedPanel): manager = ObjectProperty(None) def on_touch_up(self, touch): if not self.img3.collide_point(*touch.pos): return True else: self.lab.text ='Pos: (%d,%d)' %(touch.x, touch.y) return True def switch_to(self, header): # set the Screen manager to load the appropriate screen # linked to the tab head instead of loading content self.manager.current = header.screen # we have to replace the functionality of the original switch_to self.current_tab.state = "normal" header.state = 'down' self._current_tab = header def select_to(self, *args): try: print(args[1][0]) iw = Image.open(args[1][0]) iw.save('./phase.jpg') gray = iw.convert('1') gray.save('.gray_im.jpg') self.img3.source = './gray_im.jpg' self.img4.source = './gray_im.jpg' self.img.source = './phase.jpg' self.img.reload() self.img3.reload() self.img4.reload() except: pass def update_touch_lavel(self, label, touch): label.text = 'Pos:(%d, %d)' % (touch.x, touch.y) label.texture_update() label.pos = touch.pos label.size = label.texture_size[0] + 20, label.texture_size[1] + 20 class MainApp(App): title = 'Screen Widget' def build(self): return RootWidget() def on_pause(self): return True if __name__ == '__main___': MainApp().run() 

No estoy seguro de por qué estoy recibiendo este error. Apreciaría enormemente alguna ayuda para arreglar el código para que funcione según lo previsto.

Por favor, consulte el ejemplo para más detalles.

Ejemplo

main.py

 from kivy.app import App from kivy.uix.tabbedpanel import TabbedPanel from kivy.properties import ObjectProperty from PIL import Image class RootWidget(TabbedPanel): manager = ObjectProperty(None) img = ObjectProperty(None) img3 = ObjectProperty(None) img4 = ObjectProperty(None) lab = ObjectProperty(None) def on_touch_up(self, touch): if not self.img3.collide_point(*touch.pos): return True else: self.lab.text = 'Pos: (%d,%d)' % (touch.x, touch.y) return True def switch_to(self, header): # set the Screen manager to load the appropriate screen # linked to the tab head instead of loading content self.manager.current = header.screen # we have to replace the functionality of the original switch_to self.current_tab.state = "normal" header.state = 'down' self._current_tab = header def select_to(self, *args): try: print(args[1][0]) iw = Image.open(args[1][0]) iw.save('./phase.jpg') gray = iw.convert('1') gray.save('./gray_im.jpg') self.img3.source = './gray_im.jpg' self.img4.source = './gray_im.jpg' self.img.source = './phase.jpg' self.img.reload() self.img3.reload() self.img4.reload() except: pass def update_touch_label(self, label, touch): label.text = 'Pos:(%d, %d)' % (touch.x, touch.y) label.texture_update() label.pos = touch.pos label.size = label.texture_size[0] + 20, label.texture_size[1] + 20 class TestApp(App): title = 'Screen Widget' def build(self): return RootWidget() def on_pause(self): return True if __name__ == '__main__': TestApp().run() 

test.kv

 #:kivy 1.10.1 : manager: manager img: img img3: img3 img4: img4 lab: lab do_default_tab: False ScreenManager: id: manager Screen: id: sc1 name:'Load img' FileChooserIconView: canvas.before: Color: rgb: 0.5, 0.4, 0.5 Rectangle: pos: self.pos size: self.size on_selection: root.select_to(*args) Screen: id: sc2 name: 'Image' FloatLayout: Button: id: lab pos_hint: {"right": 0.55, 'top': 1} size_hint: .15,0.1 RelativeLayout: Image: id: img on_touch_down: str('Relative:{}'.format(args[1].pos)) pos_hint: {"left": 1, 'bottom': 1} size_hint: 0.5, 1 allow_stretch: True RelativeLayout: Image: id: img3 pos_hint: {"right": 1, 'bottom': 1} size_hint: 0.5, 1 allow_stretch: True Screen: id: sc3 name: 'Image_' FloatLayout: Image: id: img4 keep_data: True post: self.pos size: self.size TabbedPanelHeader: text: sc1.name background_color: 1, 0, 0, 1 screen: sc1.name TabbedPanelHeader: text: sc2.name background_color: 1, 1, 0, 1 screen: sc2.name TabbedPanelHeader: text: sc3.name background_color: 1, 0, 1, 1 screen: sc3.name 

Salida

Img01 Img02