画面のロック用のログインダイアログ

GUIアプリケーションのための、ログイン用のダイアログを作成する。
このダイアログでの認証が成功しなければ、メイン画面の操作ができないようにしたいときに使用する。アプリケーションの画面をロックしたいときにも使える。
wxPython料理本の3章の4に出ているコードを、最小限の機能を残して簡略化した。以下、ソース。

#!/bin/env python

import wx

class MyApp(wx.App):
    def OnInit(self):
        self.frm = TestFrame(None, title="Main")
        self.SetTopWindow(self.frm)
        self.frm.Show()
        return True

class TestFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(TestFrame, self).__init__(*args, **kwargs)

    def Show(self, show=True):
        super(TestFrame, self).Show(show)
        login = LoginDialog(self, title="Login")
        loggedIn = False
        while not loggedIn:
            dlg = login.ShowModal()
            if dlg == wx.ID_OK:
                uname = login.GetUser()
                passwd = login.GetPasswd()
                if (uname, passwd) == ("hoge", "hoge"):
                    loggedIn = True

class LoginDialog(wx.Dialog):
    def __init__(self, *args, **kwargs):
        super(LoginDialog, self).__init__(*args, **kwargs)

        self.p = wx.Panel(self)
        self._username = wx.TextCtrl(self.p)
        self._passwd = wx.TextCtrl(self.p)

        sizer = wx.FlexGridSizer(2, 2, 8, 8)
        sizer.Add(wx.StaticText(self.p, label="Username:"),
                  0, wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self._username, 0, wx.EXPAND)
        sizer.Add(wx.StaticText(self.p, label="Password:"),
                  0, wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self._passwd, 0, wx.EXPAND)

        msizer = wx.BoxSizer(wx.VERTICAL)
        msizer.Add(sizer, 1, wx.EXPAND|wx.ALL, 20)
        btnszr = wx.StdDialogButtonSizer()
        button = wx.Button(self.p, wx.ID_OK)
        button.SetDefault()
        btnszr.AddButton(button)
        msizer.Add(btnszr, 0, wx.ALIGN_CENTER|wx.ALL, 12)
        btnszr.Realize()
        self.p.SetSizer(msizer)

        vsizer = wx.BoxSizer(wx.VERTICAL)
        vsizer.Add(self.p, 1, wx.EXPAND)
        self.SetSizer(vsizer)
        self.SetInitialSize()

    def GetUser(self):
        return self._username.GetValue()

    def GetPasswd(self):
        return self._passwd.GetValue()


app = MyApp(False)
app.MainLoop()


▲上のコードの実行画面。メイン画面の上にログイン画面が現れる。


▲ユーザ名とパスワードを入力する。間違って文字列を入力すると「OK」ボタンを押してもログイン画面が消えてくれない。


▲ログイン画面が消えた。メイン画面の操作ができるようになる。この例ではメイン画面には何もコントロールが配置されていないけど。

以下は、上のコードを少し変更したもの。この形の方が、自分にとっては都合がいいときもある。

#!/bin/env python

import wx

class LoginDialog(wx.Dialog):
    def __init__(self, *args, **kwargs):
        super(LoginDialog, self).__init__(*args, **kwargs)

        self.p = wx.Panel(self)
        self._username = wx.TextCtrl(self.p)
        self._passwd = wx.TextCtrl(self.p)
        sizer = wx.FlexGridSizer(2, 2, 8, 8)
        sizer.Add(wx.StaticText(self.p, label="Username:"),
                  0, wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self._username, 0, wx.EXPAND)
        sizer.Add(wx.StaticText(self.p, label="Password:"),
                  0, wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self._passwd, 0, wx.EXPAND)

        msizer = wx.BoxSizer(wx.VERTICAL)
        msizer.Add(sizer, 1, wx.EXPAND|wx.ALL, 20)
        btnszr = wx.StdDialogButtonSizer()
        button = wx.Button(self.p, wx.ID_OK)
        button.SetDefault()
        btnszr.AddButton(button)
        msizer.Add(btnszr, 0, wx.ALIGN_CENTER|wx.ALL, 12)
        btnszr.Realize()
        self.p.SetSizer(msizer)

        vsizer = wx.BoxSizer(wx.VERTICAL)
        vsizer.Add(self.p, 1, wx.EXPAND)
        self.SetSizer(vsizer)
        self.SetInitialSize()

    def GetUser(self):
        return self._username.GetValue()

    def GetPasswd(self):
        return self._passwd.GetValue()


class MyApp(wx.App):
    def OnInit(self):
        self.frm = wx.Frame(None, -1, 'Main Window')

        login = LoginDialog(None)
        loggedIn = False
        while not loggedIn:
            dlg = login.ShowModal()
            if dlg == wx.ID_OK:
                uname = login.GetUser()
                passwd = login.GetPasswd()
                if (uname, passwd) == ("hoge", "hoge"):
                    loggedIn = True

        self.frm.Show()
        return True

app = MyApp(False)
app.MainLoop()