【问题标题】:Implementing a Password Dialog with Tkinter使用 Tkinter 实现密码对话框
【发布时间】:2013-12-02 11:12:44
【问题描述】:

我正在尝试实现一个获取用户密码的对话框。我创建了继承自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()

【问题讨论】:

    标签: python user-interface tkinter tk


    【解决方案1】:

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

    你可以使用绑定回车键:

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

    使用包装函数:

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

    您也可以改用lambda

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-20
      • 2017-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多