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

Python 在kivy中通过回调传递对象-链接对象的好主意?,python,python-3.x,kivy,kivy-language,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) #<----------- 在.kv文件中,代码为: <Apibar>: BoxLayout: orientation:

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

....
...
ToggleButton:
    id: toggle_visibility
    size_hint_x: 0.27
    text: "Hide"
    on_press: root.toggle_visibility(self) #<-----------
在.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
:
盒子布局:
方向:“垂直”
填充:“5dp”
api_输入_栏:api_输入
切换可见性按钮:切换可见性
盒子布局:
方向:“水平”
尺寸:0.5
#其他小部件的更多规则
切换按钮:
id:toggle\u可见性
尺寸:0.27
文本:“隐藏”
按:root.toggle\u visibility()
#其他小部件的更多规则
终端的回溯是:

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'
文件“main.py”,第43行,在
pictureapp().run()
文件“/usr/lib/python3/dist-packages/kivy/app.py”,第828行,运行中
runTouchApp()
文件“/usr/lib/python3/dist packages/kivy/base.py”,第504行,在runTouchApp中
EventLoop.window.mainloop()
文件“/usr/lib/python3/dist packages/kivy/core/window/window\u sdl2.py”,第663行,在mainloop中
self._mainloop()
文件“/usr/lib/python3/dist packages/kivy/core/window/window\u sdl2.py”,第405行,在mainloop中
EventLoop.idle()
文件“/usr/lib/python3/dist packages/kivy/base.py”,第342行,处于空闲状态
self.dispatch_input()
文件“/usr/lib/python3/dist packages/kivy/base.py”,第327行,在dispatch_输入中
发送后输入(*pop(0))
文件“/usr/lib/python3/dist packages/kivy/base.py”,第233行,在发送后输入中
dispatch('on_motion',etype,me)
文件“kivy/_event.pyx”,第718行,在kivy.\u event.EventDispatcher.dispatch(kivy/_event.c:7726)中
文件“/usr/lib/python3/dist packages/kivy/core/window/_init__.py”,第1188行,动态
自我派遣(“在我触地时”)
文件“kivy/_event.pyx”,第718行,在kivy.\u event.EventDispatcher.dispatch(kivy/_event.c:7726)中
文件“/usr/lib/python3/dist packages/kivy/core/window/_init__.py”,第1204行,在on_触摸屏中
如果w.dispatch('打开触摸屏',触摸屏):
文件“kivy/_event.pyx”,第718行,在kivy.\u event.EventDispatcher.dispatch(kivy/_event.c:7726)中
文件“/usr/lib/python3/dist-packages/kivy/uix/widget.py”,第457行,在on\u触控下
如果是child.dispatch('on_touch_down',touch):
文件“kivy/_event.pyx”,第718行,在kivy.\u event.EventDispatcher.dispatch(kivy/_event.c:7726)中
文件“/usr/lib/python3/dist-packages/kivy/uix/widget.py”,第457行,在on\u触控下
如果是child.dispatch('on_touch_down',touch):
文件“kivy/_event.pyx”,第718行,在kivy.\u event.EventDispatcher.dispatch(kivy/_event.c:7726)中
文件“/usr/lib/python3/dist-packages/kivy/uix/widget.py”,第457行,在on\u触控下
如果是child.dispatch('on_touch_down',touch):
文件“kivy/_event.pyx”,第718行,在kivy.\u event.EventDispatcher.dispatch(kivy/_event.c:7726)中
文件“/usr/lib/python3/dist-packages/kivy/uix/behaviors/button.py”,第151行,在on\u触控下
自动发送('在印刷机上')
文件“kivy/_event.pyx”,第714行,在kivy.\u event.EventDispatcher.dispatch(kivy/_event.c:7681)中
kivy.\u event.eventobservators.dispatch(kivy/\u event.c:13524)中的文件“kivy/\u event.pyx”,第1225行
文件“kivy/\u event.pyx”,第1109行,在kivy.\u event.eventobsers.\u调度(kivy/\u event.c:12356)中
文件“/usr/lib/python3/dist packages/kivy/lang/builder.py”,第64行,在自定义回调中
exec(\uuuukVLANG\uuuuuuu.co\u值,idmap)
文件“/home/xyzuser/project_folder/pythonprjs/pictureabarapp/picture.kv”,第37行,在
按:root.toggle\u visibility()
文件“main.py”,第35行,在可见性中
self.api\u input\u bar.text=“您的api密钥”
AttributeError:“非类型”对象没有属性“文本”

我完全按照上面提到的那样做了,但代码似乎不起作用

该问题是由于您在不适当的位置执行赋值而导致的,api\u input\u bar属于Apibar,因此如果您要建立连接,正确的位置位于Apibar下方,因为它是Apibar的范围:

<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
:
#阿皮巴镜
api_输入_栏:api_输入
切换可见性按钮:切换可见性
盒子布局:
#盒子布局范围
方向:“垂直”
填充:“5dp”
盒子布局:
方向:“水平”
尺寸:0.5
#其他小部件的更多规则
切换按钮:
id:toggle\u可见性
尺寸:0.27
文本:“隐藏”
按:root.toggle\u visibility()
#其他小部件的更多规则
在别处建立连接时,将创建一个新的ObjectProperty,但BoxLayout除外。这可以使用以下示例进行检查:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.lang.builder import Builder

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

    def toggle_visibility(self):
        # self.ids.box.api_input_bar is different of self.api_input_bar
        self.ids.box.api_input_bar.text="your api key"

Builder.load_string('''
<Apibar>:
    BoxLayout:
        id: box
        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
            TextInput:
                id: api_input
    ''')

class MyApp(App):
    def build(self):
        return Apibar()

if __name__ == '__main__':
    MyApp().run()
从kivy.app导入应用
从kivy.uix.boxlayout导入boxlayout
从kivy.properties导入ObjectProperty
从kivy.lang.builder导入生成器
类Apibar(BoxLayout):
api_输入_bar=ObjectProperty()
切换可见性按钮=ObjectProperty()
def切换_可见性(自):
#self.ids.box.api_输入_栏与self.api_输入_栏不同
self.ids.box.api\u input\u bar.text=“您的api密钥”
Builder.load_字符串(“”)
:
盒子布局:
id:盒子
方向:“垂直”
填充:“5dp”
api_输入_栏:api_输入
切换可见性按钮:切换可见性
盒子布局:
方向:“水平”
尺寸:0.5
#其他小部件的更多规则
切换按钮:
id:toggle\u可见性
尺寸:0.27
文本:“隐藏”
按:root.toggle\u visibility()
#其他小部件的更多规则
文本输入:
id:api_输入
''')
类别MyApp(应用程序):
def生成(自):
返回Apibar()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
MyApp().run()
可以提供一个可供审查的
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.lang.builder import Builder

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

    def toggle_visibility(self):
        # self.ids.box.api_input_bar is different of self.api_input_bar
        self.ids.box.api_input_bar.text="your api key"

Builder.load_string('''
<Apibar>:
    BoxLayout:
        id: box
        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
            TextInput:
                id: api_input
    ''')

class MyApp(App):
    def build(self):
        return Apibar()

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