如何解决“无效的属性名称”错误以使用 kivy 制作文件选择器?

Posted

技术标签:

【中文标题】如何解决“无效的属性名称”错误以使用 kivy 制作文件选择器?【英文标题】:How to resolve "invalid property name" error to make file chooser with kivy? 【发布时间】:2018-12-19 03:02:48 【问题描述】:

我是 kivy 的新手,我正在尝试构建一个应用程序,其中包含三个选项卡:一个用于加载图像,另一个用于并排显示图像和灰度版本,最后一个选项卡用于仅显示灰度图像。

我从this link 得到了以下信息,并希望将其用于 python 3,但我反复收到以下错误。

属性名无效

这是我目前使用的代码:

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("""
<RootWidget>:
 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()

我不确定为什么会收到此错误。对于修复代码以使其按预期工作的帮助,我将不胜感激。

【问题讨论】:

你可以改进你的代码的标识,这太可怕了。 @eyllanesc 抱歉,从我的编辑器复制和粘贴代码时,代码的格式会变得混乱?您还希望我以其他方式分享它吗? 【参考方案1】:

详情请参考示例。

示例

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

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

输出

【讨论】:

非常感谢!非常感谢! 我想请求您帮助完成另一项任务。你能帮我做一个文件夹选择器而不是文件选择器吗? ***.com/questions/51294999/…

以上是关于如何解决“无效的属性名称”错误以使用 kivy 制作文件选择器?的主要内容,如果未能解决你的问题,请参考以下文章

Qml QtQuick2'无效的属性名称“样式”(M16)' [重复]

使用python / kivy处理小部件放置以解决屏幕旋转的好方法是啥?

使用 cmd 安装 Kivy 会导致“错误:依赖关系......未解决”[关闭]

在 PyCharm 中使用 kivy 属性时,我不断收到“未解决的引用”错误

Kivy 中的数字时钟标签

如何在 Windows 中为桌面创建 kivy 应用程序?