使用wxpython开发跨平台桌面应用,设计系统的登录界面

一般的系统登统界面,设计好看一些,系统会增色不少,而常规的桌面程序,包括Web上的很多界面,都借助于背景图片的效果来增色添彩,本篇随笔介绍基于WxPython来做一个登录界面效果,并对系统登录界面在不同系统上(WIndows和MacOS) 进行测试对比,调整最佳的处理方案。

1、登录界面的设计

如前面所讲,我们在登录界面上放置一个图片占位全部,并在合适的位置上添加用户的登录账号和密码输入即可,剩下的就是对登录的请求和响应处理了。

我们基于WxPython来处理,放置图片一般就是用 wx.StaticBitmap,图片我们可以预先把他转换为嵌入的图片对象即可,如我们可以通过 img2py 命令来进行添加,把图片文件生成嵌入图片的对象。

如命令:

复制代码
img2py -a -F -n quit public/images/quit.ico testimage.py

会在对应的地方生成或者最佳对应的图片内容,如下所示:

我们把它整合在对应的文件中使用即可。

创建一个继承 wx.Frame 但是没有常规对话框的标题框,默认的样式是 style=wx.DEFAULT_FRAME_STYLE

我们不需要标题框,让对话框界面自定义关闭按钮,让它更加好看,因此设置样式 style=wx.FRAME_NO_TASKBAR
下面是对话框的界面效果,我们先看一下。

其中关闭按钮,背景按钮、登录按钮,都是我们使用图片来处理的,按钮采用 wx.BitmapButton 来处理即可。

登录界面的窗体如下所示。

复制代码
import testimage as testimage
import wx

class LoginFrame(wx.Frame):
    def __init__(self, parent, title):
        super(LoginFrame, self).__init__(parent, title=title, size=(600, 375), 
            style=wx.FRAME_NO_TASKBAR)
        self.InitUI()

    def InitUI(self):
        panel = wx.Panel(self)
        wx.StaticBitmap(panel,-1, testimage.login_backimg.Bitmap, 
            pos= (0, 0), size=(-1, -1), style=wx.BORDER_NONE)
        font = wx.Font(16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
        
        self.userInput = wx.TextCtrl(panel, -1, value="admin", style=wx.TE_PROCESS_ENTER|wx.TE_CENTER|wx.CENTER, pos=(80, 330), size=(120, 28))
        self.userInput.SetHint("输入账号")
        self.userInput.SetFont(font)

        self.passwordInput = wx.TextCtrl(panel, -1, pos =(280, 330), size=(120, 28), style=wx.TE_PASSWORD| wx.TE_PROCESS_ENTER|wx.TE_CENTER)
        self.passwordInput.SetHint("输入密码")
        self.passwordInput.SetFont(font)

        loginButton =wx.BitmapButton(panel, -1, testimage.login_btn.Bitmap, pos= (410, 328),size= (92, 30))
        self.Bind(wx.EVT_BUTTON, self.OnLogin, loginButton)

        quitButton = wx.BitmapButton(panel, -1, testimage.quit.Bitmap, pos= (560, 10),size= (32, 30))
        self.Bind(wx.EVT_BUTTON, self.OnQuit, quitButton)

        self.Centre()

上面代码,在MacOS上运行界面,还算不错,不过在WIndows上,输入框和标签都无法正常显示,需要主动鼠标单击的时候,才出现,输入焦点也不太正常,后来搜索解决方案才发现是系统界面刷新的问题,不能使用 wx.StaticBitmap,而需要使用刷新绘制背景图片的方式才可以正常,因此改动一下,使用 EVT_ERASE_BACKGROUND 事件处理的方式绘制背景方式。在初始化界面的时候,绑定该 EVT_ERASE_BACKGROUND 事件,如下代码所示。

复制代码
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBack)
复制代码
    def OnEraseBack(self, event: wx.EraseEvent):
        dc = event.GetDC()
        if not dc:
            dc = wx.ClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)
        dc.Clear()
        dc.DrawBitmap(testimage.login_backimg.Bitmap, 0, 0)

这样测试MacOS和WIndows均正常显示。

2、登录界面的优化及对接登录处理

稍作调整,在启动背景上添加一些文字显示,最终界面效果如下所示。

具体就是在绘制背景获得ClientDC 对象后绘制文本即可,如下代码所示。

复制代码
    def OnEraseBack(self, event: wx.EraseEvent):
        dc = event.GetDC()
        if not dc:
            dc = wx.ClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)
        dc.Clear()
        dc.DrawBitmap(images.login_backimg.Bitmap, 0, 0)

        colour = wx.Colour(52, 94, 150)
        dc.SetTextForeground(colour)
        dc.SetFont(
            wx.Font(16, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
        )
        rect = wx.Rect(10, 210, 580, 30)
dc.DrawLabel("基于 wxPython 开发的 GUI 应用", rect, wx.ALIGN_CENTER \| wx.ALIGN_TOP
)
rect = wx.Rect(10, 240, 580, 30)
dc.DrawLabel(
"COPYRIGHT © 2024 广州爱奇迪软件科技有限公司",
rect,
wx.ALIGN_CENTER \| wx.ALIGN_TOP,
)

为了对接实际的Python开发的FastApi后端,我们对增加一个login.py的API对接类,如下代码所示。

复制代码
from .base_api import BaseApi
from entity.common import AjaxResponse, AuthenticateResult
import requests

class Login(BaseApi):
    """登录处理--API接口类"""

    api_name = "login"

    def __init__(self):
        super().__init__(self.api_name)

    def authenticate2(self, json) -> AuthenticateResult:
        """同步登录接口

        :param json: 登录参数
            {
            "loginname": "string",
            "password": "string",
            "systemtype": "string",
            }
        :return: 登录结果
        """

        url = f"{self.base_url}/authenticate"
        data = requests.post(url, json=json).json()

        result = AjaxResponse[AuthenticateResult].model_validate(data)
        return result.result

增加登录过程的提示处理,代码如下所示。

复制代码
    def on_login(self, event):
        self.LoginSync()

    def LoginSync(self):
        # print("开始同步登录")
        login_name = self.txtLoginName.GetValue()
        login_pwd = self.txtLoginPwd.GetValue()
        if login_name == "":
            MessageUtil.show_tips(self, "请输入用户名!")
            return

        json_data = {
            "loginname": f"{login_name}",
            "password": f"{login_pwd}",
            "systemtype": "WareMis",
        }

        message = "正在尝试登陆获取令牌,请等待..."
        icon = get_bitmap("appIcon", 16)
        busy = PBI.PyBusyInfo(message, parent=self, title="登陆处理中...", icon=icon)
        try:
            wx.Yield()  # 刷新界面

            result = api_login.authenticate2(json_data)
            if result.success:
                # print("登录成功", result)
                self._accesstoken = result.accesstoken
                ApiClient.set_access_token(result.accesstoken)
                self.is_login = True
                self.Close()
            else:
                MessageUtil.show_tips(self, "用户名或密码错误!")
        except Exception as e:
            # print(e)
            MessageUtil.show_tips(
                self, "登录失败!错误信息如下:", extended_message=str(e)
            )
        finally:
            # 关闭提示框
            del busy

运行登录后,界面提示获取令牌的信息

成功后跳转到主界面窗体上。

以上就是实际使用wxpython开发跨平台桌面应用的登录界面,对接了后端FastAPI的WebAPI项目,该项目使用 FastAPI, SQLAlchemy, Pydantic, Pydantic-settings, Redis, JWT 构建的项目,数据库访问采用异步方式。 数据库操作和控制器操作,采用基类继承的方式减少重复代码,提高代码复用性。 支持Mysql、Mssql、Postgresql、Sqlite等多种数据库接入,通过配置可以指定数据库连接方式。。

相关推荐
伍华聪16 天前
如何在Python开发中实现无代码、纯配置的业务界面展示和常规数据操作的处理分析过程
python开发·pyside6/pyqt6开发
伍华聪1 个月前
在基于FastAPI的Python开发框架后端,增加阿里云短信和邮件发送通知处理
python开发
Anson Jiang2 个月前
PyTorch轻松实现CV模型:零基础到实战
pytorch·python·django·flask·python开发
伍华聪2 个月前
使用PySide6/PyQt6实现自定义窗口布局,实现类似FluentWindow效果
python开发·pyside6/pyqt6开发
伍华聪2 个月前
WxPython跨平台开发框架之主从表展示和录入的界面处理--产品报价单和明细记录的处理
python开发
伍华聪2 个月前
基于Python的FastAPI后端开发框架如何使用PyInstaller 进行打包与部署
python开发
伍华聪3 个月前
使用PySide6/PyQt6实现全国省市区的级联选择组件
python开发·pyside6/pyqt6开发
伍华聪3 个月前
基于 SocketIO 消息协议规范,并构建FastAPI上的SocketIO 应用
python开发
伍华聪3 个月前
使用PySide6/PyQt6实现系统图标的展示和选择处理
python开发·pyside6/pyqt6开发
伍华聪3 个月前
使用PySide6/PyQt6实现程序启动画面的处理
python开发·pyside6/pyqt6开发