Kivy - все динамически созданные кнопки (для l oop) возвращают один и тот же аргумент - PullRequest
0 голосов
/ 17 марта 2020

Я пытаюсь создать приложение для блокировки паролей.

Проблема, с которой я сталкиваюсь, заключается в том, что я хочу создать кнопку для каждого имени пользователя, а затем выполнить функцию при нажатии кнопки, которая требует аргументы в зависимости от нажатой кнопки. Но какая бы кнопка не нажималась, независимо от ее собственного имени пользователя, связанная с ней функция всегда принимает аргумент последней созданной кнопки. Я хочу знать, почему это происходит.

Мой код для Создание кнопок и копирование пароля для этого имени пользователя:

class CopyCredentialWindow(Screen):
    def __init__(self, **kwargs):
        super(CopyCredentialWindow, self).__init__(**kwargs)
        self.scroll = ScrollView(size_hint=(1, 1), do_scroll_y=True, do_scroll_x=False, scroll_timeout=55, bar_width=10)
        self.grid = GridLayout(cols=1, size_hint_y=None)
        self.grid.bind(minimum_height=self.grid.setter('height'))
    def on_enter(self):
        button_list = []
        for i in self.manager.credentials:
            button_list.append(Button(text=i[8:], size_hint_y=None, height=40, on_release=lambda x: self.do_accordingly(i)))
            self.grid.add_widget(button_list[-1])
        self.scroll.add_widget(self.grid)
        self.ids.grid.add_widget(self.scroll)
    def delete_dropdown(self):
        self.grid.clear_widgets()
        self.scroll.clear_widgets()
        self.ids.grid.remove_widget(self.scroll)
    def do_accordingly(self, account_name):
        credentials = self.manager.credentials
        password = credentials[account_name]
        password = password.encode()
        password = self.manager.f.decrypt(password)
        password = password.decode()
        MyApp.displaypassword = password
        pyperclip.copy(password)
        ok = PopupContent()
        popup = Popup(title='Password Copied', content=ok,
              auto_dismiss=False, size_hint=(1,1))
        ok.closebutton.bind(on_release=popup.dismiss)
        popup.open()
        self.delete_dropdown()
        self.manager.current = "Options"

self.manager.credentials - это словарь с именами пользователей в качестве ключей и паролями в качестве значений. Так, например,

self.manager.credentials = {"one":"1","two":"3","third_username":"thirdpassword"}

Здесь будут созданы 3 кнопки с именами one, two и third_username. (Обратите внимание, что в моем коде текст кнопки - i [8:], потому что у меня есть пользовательский псевдоним для каждого имени пользователя и его длина составляет 7 символов.)

Но всякий раз, когда Я нажимаю первую / вторую кнопку (кнопка с именем 'one' / 'two'), функция do_accordingly всегда получает аргумент третьей кнопки, а именно 'third_username', которая всегда возвращает пароль для третьей кнопка, независимо от того, какая кнопка нажата.

Есть идеи, почему это происходит? Спасибо.

Мой код .kv (в случае, если это имеет значение):

<CopyCredentialWindow>:
    name: "CopyCredentials"
    GridLayout:
        id: grid
        cols: 1
        AnchorLayout:
            Button:
                text: "Click here to Go Back\nSelect account to copy:"
                font_size: 20
                color: .4, .4, .8, 1
                on_release:
                    root.manager.current = "Options"
                    root.delete_dropdown()

Правка - обратите внимание, что текст кнопки отображается правильно, но функция просто не работает как ожидается.

Редактировать 2: Я получил это работает благодаря-Лотри c Вот код, который начал работать: Внутри для l oop:

            button_list.append(Button(text=i[8:], size_hint_y=None, height=40, on_release=lambda x, cred=i: self.do_accordingly(cred)))
            self.grid.add_widget(button_list[-1])

1 Ответ

0 голосов
/ 17 марта 2020

Это распространенная проблема, и решение заключается в создании виджетов в списке или в подсказке. Вы создали список с отдельными кнопками и не используете его, попробуйте это:

        for i in self.manager.credentials:
            button_list.append(Button(text=i[8:], size_hint_y=None, height=40, on_release=lambda x, cred=i: self.do_accordingly(cred)))
            self.grid.add_widget(button_list[-1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...