Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

wxPython: How to Create a Login Dialog

DZone's Guide to

wxPython: How to Create a Login Dialog

· DevOps Zone
Free Resource

Download “The DevOps Journey - From Waterfall to Continuous Delivery” to learn learn about the importance of integrating automated testing into the DevOps workflow, brought to you in partnership with Sauce Labs.

I’ve been using wxPython for quite a while now and I see certain questions come up on a fairly frequent basis. One of the popular ones is how to ask the user for their credentials before loading up the rest of the application. There are several approaches to this, but I am going to focus on a simple solution as I believe this solution can be used as the basis for more complex solutions.

Basically what we want to happen is for the user to see a login dialog where they have to enter their username and password. If they enter it correctly, then the program will continue to load and they’ll see the main interface. You see this a lot on websites with a common use case being web email clients. Desktop applications don’t include this functionality as often, although you will see it for Stamps.com’s application and for law enforcement software.

Let’s take a look at some code:

import wx
 
if "2.8" in wx.version():
    import wx.lib.pubsub.setupkwargs
    from wx.lib.pubsub import pub
else:
    from wx.lib.pubsub import pub
 
 
########################################################################
class LoginDialog(wx.Dialog):
    """
    Class to define login dialog
    """
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Dialog.__init__(self, None, title="Login")
 
        # 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)
 
        # pass 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_PASSWORD|wx.TE_PROCESS_ENTER)
        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 onLogin(self, event):
        """
        Check credentials and login
        """
        stupid_password = "pa$w0rd!"
        user_password = self.password.GetValue()
        if user_password == stupid_password:
            print "You are now logged in!"
            pub.sendMessage("frameListener", message="show")
            self.Destroy()
        else:
            print "Username or password is incorrect!"
 
########################################################################
class MyPanel(wx.Panel):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
 
 
########################################################################
class MainFrame(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Main App")
        panel = MyPanel(self)
        pub.subscribe(self.myListener, "frameListener")
 
        # Ask user to login
        dlg = LoginDialog()
        dlg.ShowModal()
 
    #----------------------------------------------------------------------
    def myListener(self, message, arg2=None):
        """
        Show the frame
        """
        self.Show()
 
if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

The majority of this code is taken up by the subclass of wx.Dialog that we are calling LoginDialog. You will notice that we have set the password text control widget to use the wx.TE_PASSWORD style, which will hide the characters that the user types into that control. The event handler is where the real action is. Here we define a silly password that we use to compare to the one that the user enters. In the real world, you would probably take a hash of the password that is entered and compare it to one that is stored in a database. Or you might send the credentials to your authentication server and have it tell you if the user’s credentials are legitimate or not. For demonstration purposes, we opt for the simple approach and just check the password. You will notice that we completely ignore what the user enters for a username. This is not realistic, but again, this is just an example.

Anyway, if the user enters the correct password, the event handler sends a message via pubsub to our MainFrame object telling it to finish loading and then the dialog is destroyed. There are other ways to tell the main frame to continue, such as using a flag in the dialog class that we can check against. Here is an implementation that demonstrates this latter method:

import wx
 
########################################################################
class LoginDialog(wx.Dialog):
    """
    Class to define login dialog
    """
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Dialog.__init__(self, None, title="Login")
        self.logged_in = False
 
        # 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)
 
        # pass 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_PASSWORD|wx.TE_PROCESS_ENTER)
        self.password.Bind(wx.EVT_TEXT_ENTER, self.onLogin)
        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 onLogin(self, event):
        """
        Check credentials and login
        """
        stupid_password = "pa$w0rd!"
        user_password = self.password.GetValue()
        if user_password == stupid_password:
            print "You are now logged in!"
            self.logged_in = True
            self.Close()
        else:
            print "Username or password is incorrect!"
 
########################################################################
class MyPanel(wx.Panel):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
 
 
########################################################################
class MainFrame(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Main App")
        panel = MyPanel(self)
 
        # Ask user to login
        dlg = LoginDialog()
        dlg.ShowModal()
        authenticated = dlg.logged_in
        if not authenticated:
            self.Close()
 
        self.Show()
 
if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

In this example, we added a flag in the dialog subclass that we called self.logged_in. If the user enters the correct password, we tell the dialog to close. This causes wxPython to return control back to the MainFrame class where we check that variable to see if the user is logged in or not. If they are not, we close the application. Otherwise we load the application.


Wrapping Up

There are a few enhancements we could add, such as setting the focus to the first text control or adding a cancel button. I’m sure you can think of a few others yourself. Overall though, this should get you started.

Discover how to optimize your DevOps workflows with our cloud-based automated testing infrastructure, brought to you in partnership with Sauce Labs

Topics:

Published at DZone with permission of Mike Driscoll, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}