raggot
raggot

Reputation: 1012

Unexpected TypeError in a function call with Kivy

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

Answers (1)

eyllanesc
eyllanesc

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

Related Questions