在wxPython中,密码样式仅适用于单行文本控件。我需要一个多行密码字段。我想了两种方法:
-
我创建了一个在每个代码点都有一个字形(实心点(的字体。然而,我可以理解用户不希望在他们的机器上随意安装字体。在wxWidgets中,您可以使用专用字体,但在wxPython中不能使用。我缺少一种为这个特定对话框动态加载这种字体的方法。
-
子类wx。TextCtrl并实现按输入的方式存储文本,但只显示单个字符。这听起来要复杂得多。我需要一些关于如何处理这件事的建议。
我确实需要这个,我已经考虑过了。因此,我正在寻找关于我上面想到的两种方式的一些想法,或者任何其他可能的实现。
在输入密码时将其存储在textctrl中!
import wx
########################################################################
class LoginDialog(wx.Dialog):
"""
Class to define login dialog
"""
def __init__(self):
wx.Dialog.__init__(self, None, title="Login")
self.logged_in = False
self.attempts = 3
self.stored_password = ""
# user info
user_sizer = wx.BoxSizer(wx.HORIZONTAL)
user_lbl = wx.StaticText(self, label="Username:")
user_sizer.Add(user_lbl, 0, wx.ALL|wx.CENTER, 5)
self.user = wx.TextCtrl(self)
user_sizer.Add(self.user, 0, wx.ALL, 5)
# password info
p_sizer = wx.BoxSizer(wx.HORIZONTAL)
p_lbl = wx.StaticText(self, label="Password:")
p_sizer.Add(p_lbl, 0, wx.ALL|wx.CENTER, 5)
self.password = wx.TextCtrl(self, style=wx.TE_MULTILINE)
self.password.Bind(wx.EVT_TEXT,self.OnMask)
p_sizer.Add(self.password, 0, wx.ALL, 5)
main_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.Add(user_sizer, 0, wx.ALL, 5)
main_sizer.Add(p_sizer, 0, wx.ALL, 5)
btn = wx.Button(self, label="Login")
btn.Bind(wx.EVT_BUTTON, self.onLogin)
main_sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
self.SetSizer(main_sizer)
def OnMask(self, event):
disp_pass = self.password.GetValue()
#Test for backspace/clear event
p_len = disp_pass.count('*')
if p_len < len(self.stored_password):
self.stored_password = self.stored_password[:p_len]
return
#Store the last input character
try:
char = disp_pass[-1]
self.stored_password = self.stored_password + char
#Mask the input
self.password.ChangeValue("*" * len(disp_pass))
except:
pass
def onLogin(self, event):
valid_password = "password1npassword2npassword3"
user_password = self.stored_password
if user_password == valid_password:
self.logged_in = True
self.Close()
return
else:
wx.MessageBox('Login failed', 'Error', wx.OK | wx.ICON_ERROR)
self.stored_password = ""
self.password.SetValue("")
self.attempts -= 1
if self.attempts < 1:
wx.MessageBox('Too many Login attempts', 'Error', wx.OK | wx.ICON_ERROR)
self.Close()
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
user_lbl = wx.StaticText(self, label="Log in Successfull")
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Main App")
panel = MyPanel(self)
dlg = LoginDialog()
dlg.ShowModal()
authenticated = dlg.logged_in
dlg.Destroy()
if not authenticated:
wx.MessageBox('Login failed', 'Error', wx.OK | wx.ICON_ERROR)
self.Destroy()
self.Show()
if __name__ == "__main__":
app = wx.App()
frame = MainFrame()
app.MainLoop()
请注意,self.password.ChangeValue()
而不是self.password.SetValue()
可防止在更新时触发EVT_TEXT。
您可以同时使用样式wx.TE_MULTILINE
和wx.TE_PASSWORD
。
...
editor = wx.TextCtrl(..., style=wx.TE_MULTILINE | wx.TE_PASSWORD)
...