wxPython "show password" 眼睛按钮

wxPython "show password" eye-button

pass_txt = wx.TextCtrl(self, style=wx.TE_PASSWORD | wx.TE_PROCESS_ENTER)

我正在使用它来创建密码框,它在插入过程中显示黑点以隐藏密码。如果 CapsLock 处于活动状态,它还会显示一个向上的小箭头。

我需要的是在框内添加一个小眼睛之类的东西,按下时显示密码。我该怎么做?

正如其他人已经评论的那样,最简单的方法是创建一个隐藏的 TextCtrl 并将其更改为密码小部件。

BoxSizer 在这些情况下非常有用。我留给你一个非常简单的例子。

#!/usr/bin/env python
# -*- coding: UTF-8 -*-


import wx

class MainFrame(wx.Frame):
    def __init__(self, *args, **kwds):        
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((463, 300))
        self.txtPassword = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_PASSWORD)
        self.txtPasswordShow = wx.TextCtrl(self, wx.ID_ANY, "")
        self.btnShowPassword = wx.Button(self, wx.ID_ANY, "Show")
        self.btnHidePassword = wx.Button(self, wx.ID_ANY, "Hide")

        self.__set_properties()
        self.__do_layout()

        # Same event handler:
        self.btnShowPassword.Bind(wx.EVT_BUTTON, self.OnBtnShowHidePass)
        self.btnHidePassword.Bind(wx.EVT_BUTTON, self.OnBtnShowHidePass)        

    def __set_properties(self):        
        self.SetTitle("frame")
        self.SetBackgroundColour(wx.Colour(185, 230, 255))

        # These widgets are hidden at the beginning:
        self.txtPasswordShow.Hide()
        self.btnHidePassword.Hide()        

    def __do_layout(self):

        #main default sizer:
        sizer_1 = wx.BoxSizer(wx.VERTICAL)

        #layout sizer:
        grid_sizer_1 = wx.FlexGridSizer(1, 2, 0, 0)

        # We add all the widgets (hidden and visible) to the appropriate BoxSizer:
        grid_sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        grid_sizer_2 = wx.BoxSizer(wx.HORIZONTAL)

        grid_sizer_2.Add(self.txtPassword, 0, 0, 0)
        grid_sizer_2.Add(self.txtPasswordShow, 0, 0, 0)
        grid_sizer_1.Add(grid_sizer_2, 1, wx.EXPAND, 0)
        
        grid_sizer_3.Add(self.btnShowPassword, 0, 0, 0)
        grid_sizer_3.Add(self.btnHidePassword, 0, 0, 0)
        grid_sizer_1.Add(grid_sizer_3, 1, wx.EXPAND, 0)
        
        sizer_1.Add(grid_sizer_1, 1, wx.ALL | wx.EXPAND, 10)
        
        self.SetSizer(sizer_1)
        self.Layout()
    
    def OnBtnShowHidePass(self, event):
        # If it is visible, we hide it:
        if self.btnShowPassword.IsShown():
            self.btnShowPassword.Hide()
            self.btnHidePassword.Show()
            self.txtPassword.Hide()
            self.txtPasswordShow.Show()
            # We pass the data from one widget to another to keep it:
            self.txtPasswordShow.SetValue(self.txtPassword.GetValue())
        else:
            self.btnShowPassword.Show()
            self.btnHidePassword.Hide()
            self.txtPassword.Show()
            self.txtPasswordShow.Hide()
            self.txtPassword.SetValue(self.txtPasswordShow.GetValue())

        self.Layout()

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MainFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True


if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

最后,我推荐使用WxGlade在wxpython中设计你的图形界面。

这有点有趣,所以这里作为 Dialog:

import wx

class LoginDialog(wx.Dialog):
    """
    Login dialog
    """
    def __init__(self):
        wx.Dialog.__init__(self, None, title="Login")
        self.logged_in = False
        self.password_shown= False

        self.username = wx.TextCtrl(self, -1)     
        self.hidden_password = wx.TextCtrl(self, -1, style=wx.TE_PASSWORD)
        self.visible_password = wx.TextCtrl(self)
        self.visible_password.Hide()
        self.lock = wx.StaticBitmap(self, -1, wx.Bitmap('lock.png'))
        self.login = wx.Button(self, -1, "Login")

        self.password_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.password_sizer.Add(self.hidden_password, 0, wx.ALL, 5)
        self.password_sizer.Add(self.visible_password, 0, wx.ALL, 5)
        self.password_sizer.Add(self.lock, 0, wx.ALL, 5)

        mainsizer= wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(self.username, 0, wx.ALL, 5)
        mainsizer.Add(self.password_sizer)
        mainsizer.Add(self.login, 0, wx.ALL, 5)

        self.lock.Bind(wx.EVT_LEFT_DOWN, self.OnToggle)
        self.login.Bind(wx.EVT_BUTTON, self.OnLogin)

        self.username.SetToolTip("Username")
        self.hidden_password.SetToolTip("Input password")
        self.visible_password.SetToolTip("Input password")
        self.lock.SetToolTip("Lock/Unlock password\nFor test purposes the password is\npassword1")

        self.SetSizer(mainsizer)

    def OnToggle(self, event):
        self.hidden_password.Show(self.password_shown)
        self.visible_password.Show(not self.password_shown)
        if not self.password_shown:
            self.visible_password.SetValue(self.hidden_password.GetValue())
            self.visible_password.SetFocus()
        else:
            self.hidden_password.SetValue(self.visible_password.GetValue())
            self.hidden_password.SetFocus()
        self.hidden_password.GetParent().Layout()
        self.password_shown = not self.password_shown

    def OnLogin(self, event):
        '''
        Perform your username/password vetting here
        or return the username/password pair for processing
        '''
        stupid_password1 = "password1"
        user_password1 = self.hidden_password.GetValue()
        if user_password1 == stupid_password1:
            self.logged_in = True
            self.Close()
        else:
            wx.MessageBox('Login failed', '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)
        # Ask user to login
        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()

锁定图像 -