python - 使用 Tkinter 实现密码对话框

标签 python user-interface tkinter tk-toolkit

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

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

关于如何解决这个问题或如何实现一般密码对话框有什么想法吗?

最好在输入 entry 后按回车键来调用 StoredPass()

最佳答案

将密码存储为 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

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

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

使用包装函数:

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

您还可以使用 lambda 代替:

self.entry.bind("<KeyRelease-Return>", lambda x: self.StorePass())

关于python - 使用 Tkinter 实现密码对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20326898/

相关文章:

python - 使用 for 循环创建对象列表 (python)

python - 如何使用 POST 请求(请求和 python3)提交联系表单?

python - 在 Python 中修改闭包的绑定(bind)变量

python-3.x - 使用 tkinter、MVC 和 Observables 设置 Entry 的值

python - Tkinter:消息小部件中 anchor 选项的正确值是多少?

python - Tkinter 弹出式键盘库

python - 使用 Python 从 HTML 中的 href 属性中提取 URL 的正则表达式

java - 通过 MouseMove 事件更改光标不起作用

java - 当我按下 JButton 时,我的框架卡住了,为什么?图形用户界面

tkinter - 如何获取当前日期以显示在 tkinter 窗口中