I'm creating a Password Manager using Python as main language, SQLite for database query and Kivy for GUI. Password manager is a program or application that allows you to store passwords and other login information in a safe location.

This piece of code is responsible for displaying all of the user's added passwords as an MD List in the password menu screen, each bit of which can be clicked and will take the user to the selected password screen where they can manage it (edit, delete or just copy it for personal use).

This is what the password menu screen looks like:

And this is what the screen for the selected password looks like:

P.s. Don't mind the awful design, it's a hastily made one for further testing and debugging.

The problematic part of this code is the password selected screen label, where it now stands for "Suiii".

self.list_of_pass is a variable that stores a list of all passwords (e.g. Netflix, Google and so on). These are entered here using function get_list_of_passwords() from a separate file. Then with a For loop we create N items of MD List, depending on the number of passwords in the database of a given user. Each item is given a text name and a function self.go_to_chosen_password(i) that will be executed when the item is clicked. The parameter of this function is i, which is supposed to give the function a unique identifier (password name) for future execution of the function. But the problem is that since "Suiii" is the last item in the list, no matter which item in the MD List is clicked, i, which was still on "Suiii" after the end of the for loop, will be responsible for the function parameter, and will therefore only output it.

Any idea how I can fix this and make the selected password screen display the exact password that was clicked in the password menu screen?

Here is a part of main.py: ...

class PasswordsMenuScreen(Screen):
    # import from Get_Data_From_Db_to_Display.py

    def on_enter(self):
        self.list_of_pass = get_list_of_passwords(...)

        for i in self.list_of_pass:
            self.item = OneLineListItem(text = i)
            self.item.bind(on_press = lambda x: self.go_to_chosen_password(i))
            self.ids.pass_list.add_widget(self.item)

    def go_to_chosen_password(self, passw):
        self.manager.get_screen('chosen_password_screen').ids.name.text = passw
        self.manager.transition.direction = 'right'
        self.manager.current = 'chosen_password_screen'


class ChosenPasswordScreen(Screen):
    pass

...

And here is a part of design.kv:

...

<PasswordsMenuScreen>:
 canvas.before:
  Color:
   rgba: (0, 0, 1, 1)
  Rectangle:
   pos: self.pos
   size: self.size
 GridLayout:
  cols: 1
  Label:
   text: 'Passwords Lab'
   font_size: '35sp'
   size_hint_y: None
   height: 150
   size_hint_x: None
   width: 1500
  GridLayout:
   cols: 2
   padding: 15, 15
   spacing: 20, 20
   GridLayout:
    cols: 2
    ScrollView:
     MDList:
      id: pass_list
      font_size: '23sp'
    Button:
     text: '+'
     size_hint_y: None
     height: 80
     size_hint_x: None
     width: 80
     on_press: root.go_to_adding_password_menu()
  GridLayout:
   cols: 1
   size_hint: 0.2, 0.15
   padding: 10, 10
   spacing: 10, 0
   Button:
    text: 'Main Menu'
    background_color: 1, 1, 1, 0
    opacity: 1 if self.state == 'normal' else 0.5
    color: 0.1, 0.7, 1, 1
    on_press: root.go_to_main_menu()

<ChosenPasswordScreen>:
 canvas.before:
  Color:
   rgba: (0, 0, 1, 1)
  Rectangle:
   pos: self.pos
   size: self.size
 GridLayout:
  cols: 1
  GridLayout:
   cols: 1
   padding: 15, 15
   spacing: 30, 30
   Label:
    id: name
    text: ''
    font_size: '35sp'
   GridLayout:
    cols: 1
    padding: 25, 25
    spacing: 30, 30
    Label:
     text: 'Login'
     font_size: '20sp'
    TextInput:
     id: login
     size_hint: 1, 0.5
    Label:
     text: 'Password'
     font_size: '20sp'
    TextInput:
     id: password
     size_hint: 1, 0.5
   GridLayout:
    cols: 2
    Button:
     text: 'Edit'
     size_hint: 0.2, 0.4
     pos_hint: {'center_x': 0.5, 'center_y': 0.6}
    Button:
     text: 'Delete'
     size_hint: 0.2, 0.4
     pos_hint: {'center_x': 0.5, 'center_y': 0.6}
  GridLayout:
   cols: 1
   size_hint: 0.2, 0.2 # 20% of window space
   padding: 10, 10
   spacing: 10, 0
   Button:
    text: 'Back'
    background_color: 0, 1, 1, 0
    opacity: 1 if self.state == 'normal' else 0.5
    color: 0.1, 0.7, 1, 1
    on_press: root.go_back_to_passwords_menu()

...

I've already tried not creating a new variable for the item in the list during for loop and writing everything on one line, but unfortunately this has the same result:

main.py

class PasswordsMenuScreen(Screen):
    # import from Get_Data_From_Db_to_Display.py

    def on_enter(self):
        self.list_of_pass = get_list_of_passwords(...)

        for i in self.list_of_pass:
            self.ids.pass_list.add_widget(OneLineListItem(text = i, on_press = lambda x: self.go_to_chosen_password(i)))

    def go_to_chosen_password(self, passw):
        self.manager.get_screen('chosen_password_screen').ids.name.text = passw
        self.manager.transition.direction = 'right'
        self.manager.current = 'chosen_password_screen'


class ChosenPasswordScreen(Screen):
    pass
0

There are 0 best solutions below