Kivy, to set buttons path in for loop?

Question:

I have created buttons as number of drivers and i used for loop for this. But created buttons path are same and F:, so what i am supposed to do?

Here is py file:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.utils import platform

class MyApp(BoxLayout):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.get_drivers()

    def get_drivers(self):
        if platform == 'win':
            import win32api   

            box_drivers = self.ids.box_drivers

box_drivers is a box layout including buttons

            drivers = win32api.GetLogicalDriveStrings()
            drivers = drivers.split('x00')[:-1] 

drivers = [‘C:’, ‘D:’, ‘E:’, ‘F:’]

            for each_driver in drivers:
                button = Button()
                button.text = each_driver
                button.bind(on_press=lambda x:self.get_path(each_driver))
                box_drivers.add_widget(button)

    def get_path(self,driver_path):

        filechooser = self.ids.file_chooser
        filechooser.path = driver_path


class SrtEditor(App):

    def build(self):
        self.title = "Srt Editor"

        return MyApp()


if __name__ == "__main__":

    SrtEditor().run()

Here is kv file:

#:import os os
<MyApp>:
    orientation: 'vertical'

    BoxLayout:          
        BoxLayout:      
            id: box_drivers
            size_hint_x:20
            orientation: 'vertical' 

            Label:
                text: 'Drivers'
                size_hint_y:None
                height: '40dp'

        FileChooserIconView:        
            size_hint_x:80
            id: file_chooser
            filters: ['*.srt*']
            on_selection: pass
            path: os.getcwd()

Here is app image:

When i press drivers, they get same path(F:)

Asked By: Furkan Guvenc

||

Answers:

You are getting the same drive because you use lambda functions that look into the current frame state

#button.bind(on_press=lambda x: self.get_path(each_driver))
#should be
button.bind(on_press=lambda x, drive=each_driver: self.get_path(drive))

read more about python function scopes to understand the issue better

Answered By: Yoav Glazner
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.