for a voteapp
suppose in it's kv
file I define a toggle button as so:
....
...
ToggleButton:
id: toggle_visibility
size_hint_x: 0.27
text: "Hide"
on_press: root.toggle_visibility(self) #<-----------
Notice the marked line above, is there anything wrong passing the widget as an argument for callback functions Instead of registering with ObjectProperty() and linking to it's id? When I do the later, I get a NoneType object returned error for an event such as press with a button for some reason, so I opted to the former.
EDIT: I have put the code for the errors that cause for the Nonetype object returned message with the traceback at the end.
The error occurs when I execute the following code:
In the main.py file:
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"
And in the .kv file the code is:
<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
And the traceback at the terminal is:
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'
I did it exactly as mentioned but the code doesn't seem to work.
The problem is caused because you are doing the assignment in an inappropriate place, api_input_bar belongs to Apibar, so if you want to make the connection the right place is below Apibar since it is its scope:
<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
When making the connection elsewhere, a new ObjectProperty is being created but for the BoxLayout. This can be checked using the following example:
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()