1

I try to bind a function (in .py) to button (in kv.) after directory selection with Filechooser (all at one Screen) as follows:

.py:

class SyllWindow(Screen): #screen where all happens

    def select(self, *args):

        if args[1]:

            filepath = args[1][0]

            try: self.label.text = filepath

            except: pass

    def output_csv(corpus_root): #function

        corpus = PlaintextCorpusReader(corpus_root, '.*') #this must be irrelevant actually
        def reduce_dip(corpus_string):
            corpus_string = corpus_string.replace("Ei", "ö")
            corpus_string = corpus_string.replace("ei", "ö")
            # reduced
            corpus_string = corpus_string.replace("ie", "ö")
            return corpus_string
        vowels = [' ','a','e','i','o','u','ä','ö','ü','A','E','I','O','U','Ä','Ö','Ü']
        cfd_syll = nltk.ConditionalFreqDist(
            (textname, num_syll)
            for textname in corpus.fileids()
            for num_syll in [len(w) for w in ''.join(char for char in reduce_dip(corpus.raw(fileids=textname)) if char in vowels).split()])
        syll_dataframe = DataFrame(cfd_syll)
        return syll_dataframe.to_csv(path + '\silben.csv')            

    pass

.kv (button block):

Button:

                            text: '.csv'
                            font_size: 14
                            on_release: self.output_csv(self.filepath)

Looks like this:

enter image description here

After pressing ".csv" I get an error AttributeError: 'Button' object has no attribute 'output_csv' I'm aware of similar issues described here, here and here, but all examples there are in Python language, while my issue seems to be more about Kivy language.

I'd be grateful for any advice.

Full error traceback:

File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\runpy.py", line 193, in _run_module_as_main
  "__main__", mod_spec)
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\runpy.py", line 85, in _run_code
  exec(code, run_globals)
File "C:\GUI Projects\gercort\main.py", line 147, in <module>
  Gercort().run()
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\app.py", line 855, in run
  runTouchApp()
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\base.py", line 504, in runTouchApp
  EventLoop.window.mainloop()
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\core\window\window_sdl2.py", line 747, in mainloop
  self._mainloop()
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\core\window\window_sdl2.py", line 479, in _mainloop
  EventLoop.idle()
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\base.py", line 342, in idle
  self.dispatch_input()
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\base.py", line 327, in dispatch_input
  post_dispatch_input(*pop(0))
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\base.py", line 293, in post_dispatch_input
  wid.dispatch('on_touch_up', me)
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\_event.cp37-win32.pyd", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
  self.dispatch('on_release')
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\_event.cp37-win32.pyd", line 703, in kivy._event.EventDispatcher.dispatch
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\_event.cp37-win32.pyd", line 1214, in kivy._event.EventObservers.dispatch
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\_event.cp37-win32.pyd", line 1098, in kivy._event.EventObservers._dispatch
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\lang\builder.py", line 64, in custom_callback
  exec(__kvlang__.co_value, idmap)
File "C:\GUI Projects\gercort\gercort.kv", line 489, in <module>
  on_release: self.output_csv(self.filepath2)
File "C:\Users\gavrk\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\kivy\weakproxy.cp37-win32.pyd", line 32, in kivy.weakproxy.WeakProxy.__getattr__

builtins.AttributeError: 'Button' object has no attribute 'output_csv'
Gavrk
  • 295
  • 1
  • 4
  • 16

1 Answers1

1
on_release: self.output_csv(self.filepath2)

self means that you are calling function from Button class, and there's no function called output_csv, so error tells you that. You defined that function in the SyllWindow class. If that button is also on that screen, just change it to

on_release: root.output_csv(root.filepath)
Lothric
  • 1,283
  • 2
  • 6
  • 11
  • Yes, the button is in the .kv's ``. – Gavrk Feb 16 '20 at 08:23
  • 1
    @Gavrk where's your filepath2 variable defined? – Lothric Feb 16 '20 at 08:35
  • I changed it to `filepath` (defined by `filepath = args[1][0]`), so accordingly the Button's `on release` is now `root.output_csv(self.filepath)`. `filepath2` was excessive, since `root.output_csv(self.filepath)` can recognize `filepath`. It was my fault to put it in the original description, sorry for puzzling you. The error is now `AttributeError: 'Button' object has no attribute 'filepath'` – Gavrk Feb 16 '20 at 09:14
  • 1
    @Gavrk Try to use also root instead of self, I changed my answer, check it again. – Lothric Feb 16 '20 at 09:20
  • Yep, just tried it out already. If I use `on_release: root.output_csv(root.filepath)` then the error is `'SyllWindow' object has no attribute 'filepath'` – Gavrk Feb 16 '20 at 09:22
  • 1
    @Gavrk instead of 'filepath' name in SyllWindow class use self.filepath everywhere. But don't change kv file. – Lothric Feb 16 '20 at 09:25
  • Then the error is `TypeError: output_csv() takes 1 positional argument but 2 were given`, what's weird because `root.filepath` what was given is actually one argument, isn't it? – Gavrk Feb 16 '20 at 09:32
  • 1
    @Gavrk That's because of button, add to your function name *args, so it would be like: def output_csv(corpus_root, *args) – Lothric Feb 16 '20 at 09:35
  • Well, then I get another error, but because of other reasons. This issue is cleared up! Thanks for your help and patience – Gavrk Feb 16 '20 at 09:38
  • May I know what kind of object is then `root.filepath`? The argument of the PlaintextCorpusReader was meant to be a string, but it seems to be some specific (two-component) object. How to extract string from that `root.filepath` from .kv file? – Gavrk Feb 16 '20 at 10:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/207923/discussion-between-lothric-and-gavrk). – Lothric Feb 16 '20 at 11:07