Рубрики
Без рубрики

wxpython: как создать диалог входа

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

Я уже некоторое время использовал WXPYPHON, и я вижу определенные вопросы на довольно частой основе. Одним из популярных является то, как спросить пользователя своих учетных данных перед загрузкой остальной части приложения. Для этого есть несколько подходов, но я собираюсь сосредоточиться на простом решении, поскольку я считаю, что это решение может быть использовано в качестве основы для более сложных решений.

В основном то, что мы хотим, чтобы пользователь мог видеть диалоговое окно входа в систему, где они должны ввести их имя пользователя и пароль. Если они вводят в это правильно, то программа будет продолжать загружаться, и они увидят основной интерфейс. Вы видите это много на веб-сайтах с общим использованием случая веб-почтовых клиентов. Настольные приложения не включают эту функциональность так часто, хотя вы увидите его для приложения Gamps.com и для программного обеспечения для правоохранительных органов. Мы будем создавать диалог, который выглядит так:

Давайте посмотрим на какой-то код:

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()

Большинство этого кодекса занимается подклассом wx.dialog что мы называем Logindialog Отказ Вы заметите, что у нас установили виджет управления паролем, чтобы использовать wx.te_password Стиль, который будет скрывать символы, которые пользователь вносит в этот контроль. Обработчик событий находится там, где реальное действие. Здесь мы определяем глупое пароль, которое мы используем для сравнения с тем, что пользователь входит. В реальном мире вы, вероятно, возьмете хэш пароль, который вводится и сравнивает его с одним, который хранится в базе данных. Или вы можете отправить учетные данные на свой сервер аутентификации, и он скажет вам, если учетные данные пользователя законно или нет. Для демонстрационных целей мы выбираем простой подход и просто проверяйте пароль. Вы заметите, что мы полностью игнорируем то, что пользователь входит в имя пользователя. Это не реалистично, но опять же, это просто пример.

В любом случае, если пользователь вводит правильный пароль, обработчик событий отправляет сообщение через PUBSUB на наш объект MainFrame, который позволяет ему завершить загрузку, а затем диалоговое окно разрушено. Существуют и другие способы сообщить основным раме, например, использование флага в диалоговом классе, на котором мы можем проверить. Вот реализация, которая демонстрирует этот последний метод:

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()

В этом примере мы добавили флаг в диалоге подкласса, который мы позвонили self.logged_in Отказ Если пользователь вводит правильный пароль, мы сообщим диалогу закрыть. Это приводит к тому, что WXPYPHON возвращает контроль обратно в класс MainFrame, где мы проверяем эту переменную, чтобы увидеть, вошел ли пользователь в системе или нет. Если они нет, мы закрываем приложение. В противном случае мы загружаем приложение.

Обертывание

Есть несколько улучшений, которые мы могли бы добавить, например, настроить фокус на первый текстовый элемент управления или добавления кнопки «Отмена». Я уверен, что вы можете подумать о нескольких других самих. В целом, тем не менее, это должно вас начать.