使用Tkinter实现密码对话框

问题描述 投票:1回答:1

我正在尝试实现一个获取用户密码的对话框。我创建了继承自PasswordDiaglog的类tk.Toplevel,但是这导致了它的执行是对父帧的非阻塞的问题。

import Tkinter as tk

class PasswordDialog(tk.Toplevel):
    def __init__(self, parent):
        tk.Toplevel.__init__(self)
        self.password = None
        self.entry = tk.Entry(self, show='*')
        self.entry.pack()
        self.button = tk.Button(self)
        self.button["text"] = "Submit"
        self.button["command"] = self.StorePass
        self.button.pack()

    def StorePass(self):
        self.password = self.entry.get()
        self.destroy()
        print '1: Password was', self.password

class MainApplication(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        self.button = tk.Button(self)
        self.button["text"] = "Password"
        self.button["command"] = self.GetPassword
        self.button.pack()

    def GetPassword(self):
        passwd = PasswordDialog(self)
        # HALT HERE 
        print '2: Password was', passwd.password

if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

通过运行我的代码提交foobar作为密码,终端中可以看到以下输出:

2: Password was None
1: Password was foobar

预期产量应为:

1: Password was foobar
2: Password was foobar

有关如何解决此问题或如何实施密码对话框的任何想法?

在输入StoredPass()之后通过点击返回来调用entry也是很好的。

python user-interface tkinter tk
1个回答
2
投票

将密码存储为MainAplication类的属性并使用传入的parent作为PasswordDialog类的句柄意味着您可以使用self.wait_window(PasswordDialog(self))阻止执行,直到PasswordDialog被销毁:

import Tkinter as tk

class PasswordDialog(tk.Toplevel):
    def __init__(self, parent):
        tk.Toplevel.__init__(self)
        self.parent = parent
        self.entry = tk.Entry(self, show='*')
        self.entry.bind("<KeyRelease-Return>", self.StorePassEvent)
        self.entry.pack()
        self.button = tk.Button(self)
        self.button["text"] = "Submit"
        self.button["command"] = self.StorePass
        self.button.pack()

    def StorePassEvent(self, event):
        self.StorePass()

    def StorePass(self):
        self.parent.password = self.entry.get()
        self.destroy()
        print '1: Password was', self.parent.password

class MainApplication(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        self.password = None
        self.button = tk.Button(self)
        self.button["text"] = "Password"
        self.button["command"] = self.GetPassword
        self.button.pack()

    def GetPassword(self):
        self.wait_window(PasswordDialog(self))
        print '2: Password was', self.password

if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

输出现在符合预期:

1: Password was foobar
2: Password was foobar

要绑定Return键,您可以使用:

self.entry.bind("<KeyRelease-Return>", self.StorePassEvent)

使用包装函数:

def StorePassEvent(self, event):
    self.StorePass()

您也可以使用lambda代替:

self.entry.bind("<KeyRelease-Return>", lambda x: self.StorePass())
© www.soinside.com 2019 - 2024. All rights reserved.