通过kivy中的回调传递对象 - 链接对象的好主意?

时间:2018-04-18 09:56:56

标签: python python-3.x kivy kivy-language

对于voteapp假设在其kv文件中我定义了一个切换按钮,如下所示:

....
...
ToggleButton:
    id: toggle_visibility
    size_hint_x: 0.27
    text: "Hide"
    on_press: root.toggle_visibility(self) #<-----------

注意上面标记的行,是否有任何错误将窗口小部件作为回调函数的参数传递而不是使用ObjectProperty()注册并链接到它的id?当我执行稍后操作时,由于某种原因,我为一个事件(例如按下按钮)返回了一个NoneType对象返回错误,因此我选择了前者。

编辑:我已经将导致Nonetype对象返回消息的错误的代码放在最后的回溯中。

执行以下代码时发生错误:

在main.py文件中:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty


class Apibar(BoxLayout):
    api_input_bar = ObjectProperty()
    toggle_visibility_button = ObjectProperty()  

    #some code here  not shown to keep minimal; only regular methods  

    def toggle_visibility(self):
        #wanting to change the text inside the text input key
        self.api_input_bar.text="your api key"

在.kv文件中,代码为:

<Apibar>:
    BoxLayout:
        orientation:"vertical"
        padding: "5dp"
        api_input_bar: api_input
        toggle_visibility_button : toggle_visibility
        BoxLayout:
              orientation: "horizontal"
              size_hint_y: 0.5
              #some more rules for other widgets
              ToggleButton:
                  id: toggle_visibility
                  size_hint_x: 0.27
                  text: "Hide"
                  on_press: root.toggle_visibility()
                  #some more rules for other widgets

终端的追溯是:

File "main.py", line 43, in <module>
     pictureapp().run()
   File "/usr/lib/python3/dist-packages/kivy/app.py", line 828, in run
     runTouchApp()
   File "/usr/lib/python3/dist-packages/kivy/base.py", line 504, in runTouchApp
     EventLoop.window.mainloop()
   File "/usr/lib/python3/dist-packages/kivy/core/window/window_sdl2.py", line 663, in mainloop
     self._mainloop()
   File "/usr/lib/python3/dist-packages/kivy/core/window/window_sdl2.py", line 405, in _mainloop
     EventLoop.idle()
   File "/usr/lib/python3/dist-packages/kivy/base.py", line 342, in idle
     self.dispatch_input()
   File "/usr/lib/python3/dist-packages/kivy/base.py", line 327, in dispatch_input
     post_dispatch_input(*pop(0))
   File "/usr/lib/python3/dist-packages/kivy/base.py", line 233, in post_dispatch_input
     listener.dispatch('on_motion', etype, me)
   File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
   File "/usr/lib/python3/dist-packages/kivy/core/window/__init__.py", line 1188, in on_motion
     self.dispatch('on_touch_down', me)
   File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
   File "/usr/lib/python3/dist-packages/kivy/core/window/__init__.py", line 1204, in on_touch_down
     if w.dispatch('on_touch_down', touch):
   File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
   File "/usr/lib/python3/dist-packages/kivy/uix/widget.py", line 457, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
   File "/usr/lib/python3/dist-packages/kivy/uix/widget.py", line 457, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
   File "/usr/lib/python3/dist-packages/kivy/uix/widget.py", line 457, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
   File "/usr/lib/python3/dist-packages/kivy/uix/behaviors/button.py", line 151, in on_touch_down
     self.dispatch('on_press')
   File "kivy/_event.pyx", line 714, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7681)
   File "kivy/_event.pyx", line 1225, in kivy._event.EventObservers.dispatch (kivy/_event.c:13524)
   File "kivy/_event.pyx", line 1109, in kivy._event.EventObservers._dispatch (kivy/_event.c:12356)
   File "/usr/lib/python3/dist-packages/kivy/lang/builder.py", line 64, in custom_callback
     exec(__kvlang__.co_value, idmap)
   File "/home/xyzuser/project_folder/pythonprjs/pictureabarapp/picture.kv", line 37, in <module>
     on_press: root.toggle_visibility()
   File "main.py", line 35, in toggle_visibility
     self.api_input_bar.text="your api key"
 AttributeError: 'NoneType' object has no attribute 'text'

我完全按照提到的那样做了,但代码似乎没有用。

1 个答案:

答案 0 :(得分:0)

问题是由于你在不适当的地方进行作业,api_input_bar属于Apibar,所以如果你想建立连接,那么正确的地方就在Apibar下面,因为它是它的范围:

asp:textbox

在其他地方建立连接时,正在为BoxLayout创建一个新的ObjectProperty。可以使用以下示例检查:

<Apibar>:
    # Apibar Scope
    api_input_bar: api_input
    toggle_visibility_button : toggle_visibility
    BoxLayout:
        # BoxLayout scope
        orientation:"vertical"
        padding: "5dp"
        BoxLayout:
            orientation: "horizontal"
            size_hint_y: 0.5
            #some more rules for other widgets
            ToggleButton:
                id: toggle_visibility
                size_hint_x: 0.27
                text: "Hide"
                on_press: root.toggle_visibility()
                #some more rules for other widgets