Reputation: 1012
I am using Kivy with Python 3.5. I'm trying to set up an App where a button press schedules a function call. A premise: this is my first application with Kivy, and I am not very good with Python. Here's my simplified code:
class MyApp(App):
def build(self):
layout = GridLayout(cols=2)
TextStream = Label(text = 'Something will be written here: ')
StartButton = Button(text = 'Start writing')
StartButton.bind(on_press=lambda x:self.start_program(freq=10))
layout.add_widget(TextStream)
layout.add_widget(StartButton)
return layout
def start_program(self, freq):
Clock.schedule_interval(self.write_something, 1.0/freq)
# Also tried Clock.schedule_interval(self.write_something(), 1.0/freq)
def write_something(self):
TextStream.text =+ 'Something '
if __name__ == '__main__':
MyApp().run()
What I get when I run the script is:
TypeError: write_something() takes 1 positional argument but 2 were given
Reading the answers to this question, about this specific error, I understood that methods in Python are actually implemented differently from how they appear in code.
More precisely, from this comment I understand that properly declaring the method write_something
giving it self
as argument is the correct way to do it. Also, from this answer I get that the number of passed arguments counted by Python should be 1+N, where N are passed in the call. I am not passing any argument in the call however.
So, are there some silent arguments passed with Kivy? Am I calling the method in the wrong way?
Edit - Error stack
As suggested by a comment, I include the entire error stack:
Traceback (most recent call last):
File "<ipython-input-1-5d17b5569154>", line 1, in <module>
runfile('/home/raggot/Projects/MyApp/scripts/_test_kivy.py', wdir='/home/raggot/Projects/MyApp/scripts')
File "/usr/local/lib/python3.5/dist-packages/spyder/utils/site/sitecustomize.py", line 705, in runfile
execfile(filename, namespace)
File "/usr/local/lib/python3.5/dist-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "/home/raggot/Projects/MyApp/scripts/_test_kivy_camera.py", line 78, in <module>
MyApp().run()
File "/usr/local/lib/python3.5/dist-packages/kivy/app.py", line 826, in run
runTouchApp()
File "/usr/local/lib/python3.5/dist-packages/kivy/base.py", line 502, in runTouchApp
EventLoop.window.mainloop()
File "/usr/local/lib/python3.5/dist-packages/kivy/core/window/window_pygame.py", line 403, in mainloop
self._mainloop()
File "/usr/local/lib/python3.5/dist-packages/kivy/core/window/window_pygame.py", line 289, in _mainloop
EventLoop.idle()
File "/usr/local/lib/python3.5/dist-packages/kivy/base.py", line 337, in idle
Clock.tick()
File "/usr/local/lib/python3.5/dist-packages/kivy/clock.py", line 581, in tick
self._process_events()
File "kivy/_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events
File "kivy/_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events
File "kivy/_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events
File "kivy/_clock.pyx", line 167, in kivy._clock.ClockEvent.tick
TypeError: write_something() takes 1 positional argument but 2 were given
Upvotes: 1
Views: 196
Reputation: 243955
When it connects any event, in this case schedule_interval
Kivy passes additional arguments to it, for that reason it throws you that error, in your case it only uses args
and you don't have any problem. In the case of Clock
, it passes the dt
which is the exact call time.
def start_program(self, freq):
Clock.schedule_interval(self.write_something, 1.0/freq)
def write_something(self, *args):
print(args)
Upvotes: 1