实战wxPython:049 - 实现一个登录窗口

2023-11-18

在很多GUI程序中,常常在应用启动开始的时候,需要一个用户登录对话框,在那里用户必须输入用户名和密码, 如果密码和用户名正确,那么程序就继续加载,显示程序的主界面。

下面我们将实现一个登录窗口,它具有以下功能:

  • 输入用户名及密码。
  • 登录,如果用户名和密码成功匹配,则显示登录成功信息, 如果登录失败,则清除输入的信息,提示重新输入。
  • 一共有三次输入机会,如果三次都出错,则直接退出应用。

在本文中我们将演示如何使用绝对布局方式和wxPython中的布局调节器Sizer来实现登录窗口的布局。

一、使用绝对位置实现布局

所谓绝对布局,就是在面板Panel上指定每个控件的绝对像素位置,指定该位置后,控件不会随窗口的大小变化而调整其位置。

import wx

class DialogLogin(wx.Dialog):

    def __init__(self, *args, **kw):
        super(DialogLogin, self).__init__(*args, **kw)

        self.InitUi()

    def InitUi(self):
        self.SetTitle("实战wxPython: 登录对话框演示")
        self.SetSize(400, 280)

        self.Bind(wx.EVT_CLOSE, self.OnClose)

        panel = wx.Panel(self)
        wx.StaticText(panel, wx.ID_ANY, "用户登录", pos = (160, 40))

        wx.StaticText(panel, wx.ID_ANY, "用户名:", pos = (80, 80), size=(40, 24))
        self.txtUsername = wx.TextCtrl(panel, wx.ID_ANY, pos = (140, 80), size=(160, 24))

        wx.StaticText(panel, wx.ID_ANY, "密码:" , pos = (80, 120), size=(40, 24))
        self.txtPassword = wx.TextCtrl(panel, wx.ID_ANY, pos = (140, 120), size=(160, 24), style = wx.TE_PASSWORD)

        btnLogin = wx.Button(panel, wx.ID_ANY, "登录", pos = (100, 180), size = (80, 24))
        btnLogin.Bind(wx.EVT_BUTTON, self.OnLogin)

        btnCancel = wx.Button(panel, wx.ID_ANY, "取消", pos = (200, 180), size = (80, 24))
        btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)

        self.inputCount = 0

        self.Centre()

    def OnClose(self, e):
        print("Destroy dialog\n")
        self.Destroy()

    def OnLogin(self, e):
        if self.txtUsername.GetValue() != "Admin":
            wx.MessageBox("用户名错误", "提示信息", wx.OK|wx.ICON_INFORMATION)
            self.CheckInput()
        elif self.txtPassword.GetValue() != "Admin":
            wx.MessageBox("密码错误", "提示信息", wx.OK|wx.ICON_INFORMATION)
            self.CheckInput()
        else:
            wx.MessageBox("登录成功", "提示信息", wx.OK|wx.ICON_INFORMATION)
            #退出应用
            self.Destroy();

    def OnCancel(self, e):
        self.inputCount = 0;
        self.txtUsername.Clear()
        self.txtPassword.Clear()
        self.txtUsername.SetFocus()

    def CheckInput(self):
        self.inputCount += 1
        if self.inputCount == 3:
            wx.MessageBox("三次错误输入,应用退出", "提示信息", wx.OK|wx.ICON_INFORMATION)
            #退出应用
            self.Destroy()
        elif self.inputCount == 2:
            wx.MessageBox("输入错误,还有一次机会", "提示信息", wx.OK|wx.ICON_INFORMATION)
        elif self.inputCount == 1:
            wx.MessageBox("输入错误,还有二次机会", "提示信息", wx.OK|wx.ICON_INFORMATION)

def main():
    app = wx.App()
    sample = DialogLogin(None)
    sample.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()

上面的代码演示了如何使用绝对布局方式来实现一个登录窗口,从代码中可以看到,我们创建的每一个子控件,都指定相对于父窗口 panel的绝对像素位置。

在代码中,我们绑定了窗口的关闭事件

self.Bind(wx.EVT_CLOSE, self.OnClose)

当我们点击窗口上的” X”按钮时,将触发这个事件,执行OnClose中的代码

def OnClose(self, e):
        print("Destroy dialog\n")
        self.Destroy()

关闭对话框。

 图1:采用绝对布局实现的登录窗口

当输入的用户名为"Admin"和密码都为"Admin",显示登录成功对话框,点击确定后,将退出应用。

二、使用Sizer实现布局

使用各种Sizer调节器来实现布局的一个重要优点就是,当窗口的大小发生变化时,窗口内的控件会根据父窗口的变化来调整自身相对于父窗口的位置,这样,最终窗口的显示效果相对于绝对布局来说,会更协调和美观。

import wx

class DialogLogin(wx.Dialog):

    def __init__(self, *args, **kw):
        super(DialogLogin, self).__init__(*args, **kw)

        self.InitUi()

    def InitUi(self):
        self.SetTitle("实战wxPython: 登录对话框演示")
        self.SetSize(400, 280)

        self.Bind(wx.EVT_CLOSE, self.OnClose)

        panel = wx.Panel(self)

        mainSizer = wx.BoxSizer(wx.VERTICAL)

        # 顶部的提示信息
        txtLogin = wx.StaticText(panel, wx.ID_ANY, "用户登录")
        mainSizer.Add(txtLogin,  0, wx.ALL|wx.CENTER, 20)

        # 用户名和密码
        titleUsername = wx.StaticText(panel, wx.ID_ANY, "用户名:")
        titlePassword = wx.StaticText(panel, wx.ID_ANY, "密码:")
        self.textUsername = wx.TextCtrl(panel, wx.ID_ANY, size=(160,24));
        self.textPassword = wx.TextCtrl(panel, wx.ID_ANY, size=(160,24), style = wx.TE_PASSWORD)

        fgs = wx.FlexGridSizer(2, 2, 20, 20)
        fgs.AddMany([(titleUsername), (self.textUsername, 1, wx.EXPAND),
                     (titlePassword), (self.textPassword, 1, wx.EXPAND)])
        fgs.AddGrowableRow(1,1)
        fgs.AddGrowableCol(1, 1)

        mainSizer.Add(fgs, proportion=0, flag=wx.CENTER, border=40)

        btnSizer = wx.BoxSizer(wx.HORIZONTAL)

        btnLogin = wx.Button(panel, wx.ID_ANY, "登录", size = (80, 24))
        btnLogin.Bind(wx.EVT_BUTTON, self.OnLogin)

        btnCancel = wx.Button(panel, wx.ID_ANY, "取消", size = (80, 24))
        btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)

        btnSizer.Add(btnLogin)
        btnSizer.Add(btnCancel, flag=wx.LEFT, border=40)

        mainSizer.Add((-1, 40))
        mainSizer.Add(btnSizer, 1, wx.CENTER, border = 20)

        panel.SetSizer(mainSizer)

        self.inputCount = 0

        self.Centre()

    def OnClose(self, e):
        print("Destroy dialog\n")
        self.Destroy()

    def OnLogin(self, e):
        if self.textUsername.GetValue() != "Admin":
            wx.MessageBox("用户名错误", "提示信息", wx.OK|wx.ICON_INFORMATION)
            self.CheckInput()
        elif self.textPassword.GetValue() != "Admin":
            wx.MessageBox("密码错误", "提示信息", wx.OK|wx.ICON_INFORMATION)
            self.CheckInput()
        else:
            wx.MessageBox("登录成功", "提示信息", wx.OK|wx.ICON_INFORMATION)
            #退出应用
            self.Destroy();

    def OnCancel(self, e):
        self.inputCount = 0;
        self.textUsername.Clear()
        self.textPassword.Clear()
        self.textUsername.SetFocus()

    def CheckInput(self):
        self.inputCount += 1
        if self.inputCount == 3:
            wx.MessageBox("三次错误输入,应用退出", "提示信息", wx.OK|wx.ICON_INFORMATION)
            #退出应用
            self.Destroy()
        elif self.inputCount == 2:
            wx.MessageBox("输入错误,还有一次机会", "提示信息", wx.OK|wx.ICON_INFORMATION)
        elif self.inputCount == 1:
            wx.MessageBox("输入错误,还有二次机会", "提示信息", wx.OK|wx.ICON_INFORMATION)

def main():
    app = wx.App()
    sample = DialogLogin(None)
    sample.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()

在上面的代码中,我们使用Sizer调节器来实现登录窗口的布局:

mainSizer = wx.BoxSizer(wx.VERTICAL)

首先我们创建一个垂直布局的调节器mainSizer作为我们的主调节器

txtLogin = wx.StaticText(panel, wx.ID_ANY, "用户登录")
mainSizer.Add(txtLogin,  0, wx.ALL|wx.CENTER, 20)

然后我们添加”用户登录”的静态文本提示信息,将其添加到 mainSizer中,并水平居中。

titleUsername = wx.StaticText(panel, wx.ID_ANY, "用户名:")
titlePassword = wx.StaticText(panel, wx.ID_ANY, "密码:")
self.textUsername = wx.TextCtrl(panel, wx.ID_ANY, size=(160,24));
 self.textPassword = wx.TextCtrl(panel, wx.ID_ANY, size=(160,24), style = wx.TE_PASSWORD)

 fgs = wx.FlexGridSizer(2, 2, 20, 20)
 fgs.AddMany([(titleUsername), (self.textUsername, 1, wx.EXPAND),
                (titlePassword), (self.textPassword, 1, wx.EXPAND)])
 fgs.AddGrowableRow(1,1)
fgs.AddGrowableCol(1, 1)

 mainSizer.Add(fgs, proportion=0, flag=wx.CENTER, border=40)

然后,我们生成用户名和密码输入解码,使用一个wx.FlexGridSizer调节器来完成对它们的布局。并将其添加到mainSizer中。

btnSizer = wx.BoxSizer(wx.HORIZONTAL)

btnLogin = wx.Button(panel, wx.ID_ANY, "登录", size = (80, 24))
 btnLogin.Bind(wx.EVT_BUTTON, self.OnLogin)

 btnCancel = wx.Button(panel, wx.ID_ANY, "取消", size = (80, 24))
 btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)

 btnSizer.Add(btnLogin)
 btnSizer.Add(btnCancel, flag=wx.LEFT, border=40)
创建一个水平布局btnSizer, 将“登录”和“取消”按钮放入其中。
mainSizer.Add((-1, 40))

在主调节器中添加垂直方向40像素的间隔。

mainSizer.Add(btnSizer, 1, wx.CENTER, border = 20)

将btnSizer添加到主调节器mainSizer,完成整个布局。

 图2:采用Sizer调节器实现的登录窗口

当输入的用户名为"Admin"和密码都为"Admin",显示登录成功对话框,点击确定后,将退出应用。

三、本文知识点

  • 熟悉绝对布局和相对布局。
  • 运用wxPyhton中的控件实现一个布局。
  • 熟悉wx.Dialog的使用方法。
  • 熟悉各种Sizer调节器的使用方法。
  • 熟悉wx.MessageBox的使用方法。

前一篇:实战wxPython:048 - Book控件(第二部分)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实战wxPython:049 - 实现一个登录窗口 的相关文章

随机推荐

  • Android 更新UI方法的深度解析

    1 Handler public class SecondActivity extends Activity private static final int MSG WHAT 101 TextView tv Button btn priv
  • Unity 制作动画 - Animation 的使用

    1 unity 顶部导航栏点击 Window gt Animation 打开 Animation 窗口 通过这个窗口可以创建 编辑动画 也可以查看导入的动画 Animation 窗口同一时间只能查看 编辑同一段Clip中的动画 2 选中 H
  • MySQL的auto_increment使用

    说明 总结自 mysql技术内幕 第5版 创建auto increment列要遵循如下规则 每个表只能有一个列具有auto increment属性 且必须为整数数据类型 当然 也支持浮点类型 但强烈不建议 该列必须建立索引 最常见的就是使用
  • 2014年3月8日星期六(DEMO8-5恒定着色)

    恒定着色是在多边形由一种材质构成 多边形的每个点的面法线都相同 因此 只需对一个顶点的像素的光照情况对整个多边形进行着色 对于平面组成的物体 是可行的 但是如果对曲面组成的物体 会导致物体看起来由多边形组成 在16位着色下 光照步骤为 1
  • 【漏洞复现】利用禅道系统RCE命令执行漏洞反弹shell

    0x00 漏洞爆出来已经有些日子了 今天实测了一下 记录一下测试过程 0x01 影响范围 开源版 17 4 lt 禅道 lt 18 0 beta1 旗舰版 v3 4 lt 禅道 lt v4 0 beta1 企业版 v7 4 lt 禅道 lt
  • H2,Derby,HSQL内存数据库体验

    前一段时间接触了下spring支持的3种嵌入式数据库 希望能替代mysql 结果不太理想 记录一下 1 使用背景 小组希望有独立的单测数据库 这样能保证测试数据的稳定性 本身项目用spring 优先选择spring自带的3个嵌入式数据库 2
  • read tcp 192.168.0.106:56298->185.199.111.153:80: wsarecv: An existing connection was forcibly close

    解决 read tcp 192 168 0 106 56298 gt 185 199 111 153 80 wsarecv An existing connection was forcibly close 问题 问题描述 问题原因 解决办
  • pytest自带测试报告修改与汉化

    话不多说 大家直接看这篇文章吧 我也是根据这篇文章调整的 这篇算是详细 详尽的了 转载链接地址 https www cnblogs com linuxchao p linuxchao pytest html html 最后的汉化插件我没有用
  • python控制系统操作-控制text文本内容的选取与输出

    python控制系统操作 控制text文本内容的选取与输出 1 首先我们查看一下简单文本的内容 txt T QWE GGG Sat AbsoluteDlg cpp 777 m Progress gt Get gt Set RRC T QWE
  • JVM的构成 (类加载子系统、执行引擎、运行时数据区)

    目录 JVM由三部分组成 1 类加载子系统 可以根据指定的全限定名来载入类或接口 Java类加载机制 trigger333的博客 CSDN博客 java类加载的机制 2 执行引擎 负责执行那些包含在被载入类的方法中的指令 3 运行时数据区
  • 刷脸支付技术对接可以代理可以贴牌

    购物付款时 不用打开手机 只是看一眼支付设备 就能完成付款 今年以来 刷脸支付在大小商店 餐馆逐渐铺开 消费者和商家在感到新鲜 好奇的同时也发现 这一设备利用率较低 体验也没有二维码支付好 此外还存在个人信息泄露的风险 刷脸支付未来如何 市
  • cpu是几核的怎么查看

    文章目录 一 Windows下 二 Linux下 一 Windows下 通过任务管理器查看 windows下任务管理器的打开方式较多 比如 Win x 选择任务管理器 T Win R 输入taskmgr并点击回车键 打开任务管理器 Ctrl
  • DC-DC自举电容(BOOT)几个问题

    在BUCK电路中 经常会看到一个电容连接在芯片的SW和boot管脚之间 这个电容称之为自举电容 关于这个电容 有以下几个问题 自举电容有什么用 以MPS的buck芯片MP1484为例 规格书中芯片的BS管脚说明如下 在BS和SW之间接一个0
  • 51单片机C语言跑马灯,51单片机上实现控制跑马灯

    在MCS一51单片机的控制系统中 它的四个并行8位输入输出端口P0一P3是我们经常使用的 在并行端口的编程学习中 跑马灯 是单片机并行端口输出控制的典型实例 所谓跑马灯 是指将八个发光二极管分别连接到单片机的某一并行端口的八根线上 通过编程
  • wordpress 4.6 RCE漏洞利用(CVE-2016-10033)

    一 漏洞描述 当WordPress 使用 PHPMailer 组件向用户发送邮件 攻击者在找回密码时会使用PHPmailer发送重置密码的邮件 利用substr 字符串截取函数 run 系统调用函数 等构造payload 即可进行远程命令执
  • 区块链:Solidity值类型(布尔Boolens&整型Integer)

    Solidity Types 布尔 Booleans bool 可能的取值为常量值true和false 支持的运算符 逻辑非 逻辑与 逻辑或 等于 不等于 备注 运算符 和 是短路运算符 如f x g y 当f x 为真时 则不会继续执行g
  • HTTP请求返回状态码

    消息 代表请求已被接收 需要继续处理 临时响应 100 Continue 告知客户部分响应已被服务器接收 客户端应继续发送请求 成功 服务器已经接收理解并接受请求 200 OK 请求成功 返回想要的数据 正常状态 201 Created 已
  • 软件测试方法汇总

    软件测试方法种类繁多 记忆起来混乱 如果把软件测试方法进行分类 就会清晰很多 我参考一些书籍和网上的资料 把常用的软件测试方法列出来 让大家对软件测试行业有个总体的看法 从测试设计方法分类 测试名称 测试内容 Black box黑盒测试 把
  • 洛谷-【入门4】数组

    1 小鱼比可爱 题目描述 人比人 气死人 鱼比鱼 难死鱼 小鱼最近参加了一个 比可爱 比赛 比的是每只鱼的可爱程度 参赛的鱼被从左到右排成一排 头都朝向左边 然后每只鱼会得到一个整数数值 表示这只鱼的可爱程度 很显然整数越大 表示这只鱼越可
  • 实战wxPython:049 - 实现一个登录窗口

    在很多GUI程序中 常常在应用启动开始的时候 需要一个用户登录对话框 在那里用户必须输入用户名和密码 如果密码和用户名正确 那么程序就继续加载 显示程序的主界面 下面我们将实现一个登录窗口 它具有以下功能 输入用户名及密码 登录 如果用户名