Search code examples
pythonkivykivy-language

Kivy: How select directory by FileChooser without kv language?


In Kivy manual is example for using FileChooser with kivy language. I want to use FileChooser only in python code. When I mark directory by mouse, press button Select Dir and actually value is in variable FileChooser.path. Selection without using this button has not result. In kv file from example is used event on_selection, I binded this event with my function, but without effect.

My questions:

  1. How do I get value to path with only mouse using?
  2. Which class use event on_selection?

Thank You!

class Explorer(BoxLayout):   
    def __init__(self, **kwargs):
        super(Explorer,self).__init__(**kwargs)

        self.orientation = 'vertical'
        self.fichoo = FileChooserListView(size_hint_y = 0.8)
        self.add_widget(self.fichoo)

        control   = GridLayout(cols = 5, row_force_default=True, row_default_height=35, size_hint_y = 0.14)
        lbl_dir   = Label(text = 'Folder',size_hint_x = None, width = 80)
        self.tein_dir  = TextInput(size_hint_x = None, width = 350)
        bt_dir = Button(text = 'Select Dir',size_hint_x = None, width = 80)
        bt_dir.bind(on_release =self.on_but_select)

        self.fichoo.bind(on_selection = self.on_mouse_select)

        control.add_widget(lbl_dir)
        control.add_widget(self.tein_dir)
        control.add_widget(bt_dir)

        self.add_widget(control)

        return

    def on_but_select(self,obj):
        self.tein_dir.text = str(self.fichoo.path)
        return

    def on_mouse_select(self,obj):
        self.tein_dir.text = str(self.fichoo.path)
        return

    def on_touch_up(self, touch):
        self.tein_dir.text = str(self.fichoo.path)
    return super().on_touch_up(touch)
        return super().on_touch_up(touch)

Solution

  • Few changes need to be done.

    There's no such event on_selection, there's property selection in FileChooserListView. You can use functions on_<propname> inside class that has these property, but when you use bind, you should use only bind(<propname>=.

    Second thing is that by default as you can see in the doc selection contains list of selected files, not directories. To make directories actually selctable, you should change dirselect property to True.

    Last on is on_mouse_select signature: property fires with it's value, you should count that.

    Summary changes are:

    self.fichoo.dirselect = True
    self.fichoo.bind(selection = self.on_mouse_select)
    
    # ... and
    
    def on_mouse_select(self, obj, val):
    

    After that you would be do the same as with button.


    If you want to fill input with not actually path you're in, but selected path, you can do following:

    def on_touch_up(self, touch):
        if self.fichoo.selection:
            self.tein_dir.text = str(self.fichoo.selection[0])
        return super().on_touch_up(touch)