Автор оригинала: 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, где мы проверяем эту переменную, чтобы увидеть, вошел ли пользователь в системе или нет. Если они нет, мы закрываем приложение. В противном случае мы загружаем приложение.
Обертывание
Есть несколько улучшений, которые мы могли бы добавить, например, настроить фокус на первый текстовый элемент управления или добавления кнопки «Отмена». Я уверен, что вы можете подумать о нескольких других самих. В целом, тем не менее, это должно вас начать.