Kivy'对象没有属性'错误

时间:2018-03-23 06:00:06

标签: python kivy textinput kivy-language

我是python和Kivy编程的新手,因此遇到麻烦,可能会在这里提出简单的问题,但现在对我来说这是一个很大的障碍。 我正在用kivy开发GUI。我有一些TextInputs获取数值。在所有文本输入之后,我有一个“确定”按钮,它可以获取所有值并处理它们。 我在.kv文件中从同一个类调用函数时遇到错误。

main.py文件:

# File name: jwelkreator.py
import kivy
kivy.require('1.7.0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.anchorlayout import AnchorLayout

Builder.load_file('simpleForm.kv')
...
...

class JwelKreator(AnchorLayout):
    pass

class JwelKreatorApp(App):
    def build(self):
        return JwelKreator()

if __name__=="__main__":
    JwelKreatorApp().run()

主要的kv文件

# File name: jwelkreator.kv
#:kivy 1.7.0
<JwelKreator>:
    AnchorLayout:
        anchor_x: 'left'
        anchor_y: 'top'
        MyLayout:
            id: _tool_box
            size_hint: None,0.75
            width: 300
   ...
   ...

simpleForm.py 用于文本输入。

import kivy

from kivy.app import App
from kivy.lang import Builder
from kivy.config import Config

from kivy.uix.boxlayout import BoxLayout

class LblTxt(BoxLayout):
    pass
class MyLayout(BoxLayout):
    def print_something(self):
        print "Hello"

simpleForm.kv TextInput Layout

<LblTxt@BoxLayout>:
    id:LblTxtid
    orientation: 'horizontal'      
    lblTxtIn: 'default'
    theTxt: iAmTxt
    Label:
        text: root.lblTxtIn
        size_hint: 1,0.5
    TextInput:
        id: iAmTxt  
        multiline: False
        hint_text: "numeric only"           
        input_filter: 'int'
        size_hint: 0.5,None
        height: 30
<MyLayout@BoxLayout>:  
    orientation: 'vertical'

    LblTxt:   
        id: lt0
        lblTxtIn: 'Base Layers'

    LblTxt:   
        id: lt1
        lblTxtIn: 'Base exposer time(ms)'

    LblTxt:   
        id: lt2
        lblTxtIn: 'Min Support Height(mm)'

    LblTxt:   
        id: lt3
        lblTxtIn: 'Support Layers'

    LblTxt:   
        id: lt4
        lblTxtIn: 'Support exposer time(ms)'

    LblTxt:   
        id: lt5
        lblTxtIn: 'Job exposer time(ms)'

    Label:
        text:"Number of Layers"
    Button:
        text: 'OK'
        size_hint: 0.5,None
        height: 30
        on_release: root.print_something()

按“确定”按钮时,属性为“错误生成”。

Traceback (most recent call last):
   File "jwelkreator.py", line 21, in <module>
     JwelKreatorApp().run()
   File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 600, in run
     runTouchApp()
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 454, in runTouchApp
     EventLoop.window.mainloop()
   File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_pygame.py", line 325, in mainloop
     self._mainloop()
   File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_pygame.py", line 231, in _mainloop
     EventLoop.idle()
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 297, in idle
     self.dispatch_input()
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 284, in dispatch_input
     post_dispatch_input(*pop(0))
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 253, in post_dispatch_input
     wid.dispatch('on_touch_up', me)
   File "_event.pyx", line 285, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:4184)
   File "/usr/lib/python2.7/dist-packages/kivy/uix/button.py", line 140, in on_touch_up
     self.dispatch('on_release')
   File "_event.pyx", line 281, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:4134)
   File "simpleForm.kv", line 1, in <module>
     <LblTxt@BoxLayout>:
 AttributeError: 'MyLayout' object has no attribute 'print_something'

我被困在这里而没有办法解决它。有什么我想念的吗?

修改 @eyllanesc:根据你的建议,我从我的kv类名中删除了@BoxLayout。当我从main.kv调用MyLayout时,我的主.kv文件出错了

MyLayout:
            id: _tool_box
            size_hint: None,0.75
            width: 300

ERROR:

Traceback (most recent call last):
   File "jwelkreator.py", line 21, in <module>
     JwelKreatorApp().run()
   File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 577, in run
     root = self.build()
   File "jwelkreator.py", line 18, in build
     return JwelKreator()
   File "/usr/lib/python2.7/dist-packages/kivy/uix/anchorlayout.py", line 62, in __init__
     super(AnchorLayout, self).__init__(**kwargs)
   File "/usr/lib/python2.7/dist-packages/kivy/uix/layout.py", line 61, in __init__
     super(Layout, self).__init__(**kwargs)
   File "/usr/lib/python2.7/dist-packages/kivy/uix/widget.py", line 163, in __init__
     Builder.apply(self)
   File "/usr/lib/python2.7/dist-packages/kivy/lang.py", line 1429, in apply
     self._apply_rule(widget, rule, rule)
   File "/usr/lib/python2.7/dist-packages/kivy/lang.py", line 1534, in _apply_rule
     self._apply_rule(child, crule, rootrule)
   File "/usr/lib/python2.7/dist-packages/kivy/lang.py", line 1496, in _apply_rule
     cls = Factory_get(cname)
   File "/usr/lib/python2.7/dist-packages/kivy/factory.py", line 91, in __getattr__
     raise FactoryException('Unknown class <%s>' % name)
 kivy.factory.FactoryException: Unknown class <MyLayout>

1 个答案:

答案 0 :(得分:1)

问题

您正在 AttributeError:&#39; MyLayout&#39;对象没有属性&#39; print_something&#39; ,因为它无法找到函数 print_something

解决方案

有关详细信息,请参阅说明,示例和输出。

说明

jwelkreator.py

  1. 从simpleForm导入MyLayout
  2. 添加
  3. 删除 Builder.load_file(&#39; simpleForm.kv&#39;)
  4. jwelkreator.kv

    添加#:include simpleForm.kv 以包含外部kivy文件。

    include <file> - Kivy Language

      

    包含外部kivy文件。这允许您将复杂的小部件拆分为自己的文件。

    simpleForm.py

    您不必定义动态类 LblTxt(BoxLayout) ,因为您已在kv文件中定义它。

    Dynamic Classes - Programming Guide » Kv language

      

    此类仅由此规则的声明创建,继承自Button类,允许我们更改默认值并为其所有实例创建绑定,而无需在Python端添加任何新代码。

    simpleform.kv

    因为在Python脚本simpleForm.py中,你已经定义了类MyLayout属于BoxLayout,所以你不能在kv文件中继承它。替换&lt; MyLayout @ BoxLayout&gt;与&lt; MyLayout&gt;

    实施例

    jwealkreator.py

    from kivy.app import App
    from kivy.uix.anchorlayout import AnchorLayout
    from simpleForm import MyLayout
    
    
    class JwelKreator(AnchorLayout):
        pass
    
    
    class JwelKreatorApp(App):
    
        def build(self):
            return JwelKreator()
    
    
    if __name__ == "__main__":
        JwelKreatorApp().run()
    

    jwealkreator.kv

    # File name: jwelkreator.kv
    #:kivy 1.10.0
    #:include simpleform.kv
    
    <JwelKreator>:
        anchor_x: 'left'
        anchor_y: 'top'
        MyLayout:
            id: _tool_box
            size_hint: None,0.75
            width: 300
    

    simpleForm.py

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    
    
    class MyLayout(BoxLayout):
        def print_something(self):
            print("Hello")
    
    
    class SimpleFormApp(App):
    
        def build(self):
            return MyLayout()
    
    
    if __name__ == "__main__":
        SimpleFormApp().run()
    

    simpleform.kv

    #:kivy 1.10.0
    
    <LblTxt@BoxLayout>:
        id:LblTxtid
        orientation: 'horizontal'
        lblTxtIn: 'default'
        theTxt: iAmTxt
        Label:
            text: root.lblTxtIn
            size_hint: 1,0.5
        TextInput:
            id: iAmTxt
            multiline: False
            hint_text: "numeric only"
            input_filter: 'int'
            size_hint: 0.5,None
            height: 30
    
    <MyLayout>:
        orientation: 'vertical'
    
        LblTxt:
            id: lt0
            lblTxtIn: 'Base Layers'
    
        LblTxt:
            id: lt1
            lblTxtIn: 'Base exposer time(ms)'
    
        LblTxt:
            id: lt2
            lblTxtIn: 'Min Support Height(mm)'
    
        LblTxt:
            id: lt3
            lblTxtIn: 'Support Layers'
    
        LblTxt:
            id: lt4
            lblTxtIn: 'Support exposer time(ms)'
    
        LblTxt:
            id: lt5
            lblTxtIn: 'Job exposer time(ms)'
    
        Label:
            text:"Number of Layers"
        Button:
            text: 'OK'
            size_hint: 0.5,None
            height: 30
            on_release: root.print_something()
    

    输出

    Img01 - App Startup Img02 - Hello displayed after click OK button