0

我正在尝试制作密码储物柜应用程序。

我面临的问题是我想为每个用户名创建一个按钮,然后在单击按钮时执行一个功能,该功能根据单击的按钮采用不同的参数。 但是无论单击哪个按钮,无论它自己的用户名如何,与之关联的函数总是采用最后一个按钮创建的参数。我想知道为什么会这样。

我用于创建按钮和复制该用户名密码的代码:

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 个按钮,名称分别为 1、2 和 third_username。(请注意,在我的代码中,Button 的文本是 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: 感谢-Lothric,我让它工作了 这是开始工作的代码:在for循环内:

            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])
4

1 回答 1

0

这是常见的问题,解决方案是在列表或字典中创建小部件。您创建了带有单独按钮的列表并且您不使用它,试试这个:

        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])
于 2020-03-17T16:11:11.513 回答