Location>code7788 >text

Developing cross-platform desktop applications using wxpython and designing the system's login interface

Popularity:324 ℃/2024-11-20 09:48:44

General system login interface, the design looks good, the system will add a lot of color, and conventional desktop programs, including many interfaces on the Web, with the help of the effect of the background image to add color, this essay introduces the effect of the login interface based on WxPython to do a login interface, and the system login interface on different systems (WIndows and MacOS) to test the comparison and adjust the optimal This article describes how to make a login screen effect based on WxPython.

1、Design of login interface

As mentioned earlier, we place an image placeholder all over the login screen and add the user's login and password inputs in the appropriate places, and the rest is the request and response processing for the login.

We are based on WxPython to deal with, place the picture is generally used , the picture we can pre-convert him into an embedded image object can be, such as we can add through the img2py command to generate the image file embedded image object.

As ordered:

img2py -a -F -n quit public/images/ 

It will generate or optimize the corresponding image content in the corresponding place, as shown below:

Let's just integrate it and use it in the corresponding file.

Create a caption box that inherits but does not have a regular dialog box, the default style isstyle=wx.DEFAULT_FRAME_STYLE

We don't need a title box and let the dialog interface customize the close button to make it look better, so set the stylestyle=wx.FRAME_NO_TASKBAR
Here is the interface effect of the dialog box, let's take a look at it.

The close button, the background button, and the login button are all handled by us using images, and the buttons are handled by us.

The form for the login screen is shown below.

import testimage as testimage
import wx

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

    def InitUI(self):
        panel = (self)
        (panel, -1, testimage.login_backimg.Bitmap, 
            pos= (0, 0), size=(-1, -1), style=wx.BORDER_NONE)
        font = (16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
        
         = (panel, -1, value="admin", style=wx.TE_PROCESS_ENTER|wx.TE_CENTER|, pos=(80, 330), size=(120, 28))
        ("Enter account number")
        (font)

         = (panel, -1, pos =(280, 330), size=(120, 28), style=wx.TE_PASSWORD| wx.TE_PROCESS_ENTER|wx.TE_CENTER)
        ("enter a password")
        (font)

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

        quitButton = (panel, -1, , pos= (560, 10),size= (32, 30))
        (wx.EVT_BUTTON, , quitButton)

        ()

The above code, running interface on MacOS, not bad, but on WIndows, the input box and labels can not be displayed properly, the need for active mouse click, only when it appears, the input focus is not quite normal, and then search for a solution only to find out that it is the system interface refreshes the problem, can not be used! In order to draw the background image, we need to use the refresh method to draw the background image properly, so we change it to use the EVT_ERASE_BACKGROUND event to draw the background method. When initializing the interface, bind the EVT_ERASE_BACKGROUND event as shown in the following code.

(wx.EVT_ERASE_BACKGROUND, )
    def OnEraseBack(self, event: ):
        dc = ()
        if not dc:
            dc = (self)
            rect = ().GetBox()
            (rect)
        ()
        (testimage.login_backimg.Bitmap, 0, 0)

This tests both MacOS and WIndows to display properly.

 

2、Optimization of login interface and docking login processing

A little adjustment, add some text display on the startup background, the final interface effect is shown below.

Specifically, the background is drawn to obtain the ClientDC object after the text can be drawn, as shown in the following code.

    def OnEraseBack(self, event: ):
        dc = ()
        if not dc:
            dc = (self)
            rect = ().GetBox()
            (rect)
        ()
        (images.login_backimg.Bitmap, 0, 0)

        colour = (52, 94, 150)
        (colour)
        (
            (16, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
        )
        rect = (10, 210, 580, 30)
        (
            "GUI application based on wxPython development", rect, wx.ALIGN_CENTER | wx.ALIGN_TOP
        )
        rect = (10, 240, 580, 30)
        (
            "COPYRIGHT © 2024 Guangzhou Aqidi Software Technology Co.
            rect,
            wx.ALIGN_CENTER | wx.ALIGN_TOP, )
        )

In order to interface with the actual Python-developed FastApi backend, we add an API interface class as shown in the following code.

from .base_api import BaseApi
from  import AjaxResponse, AuthenticateResult
import requests

class Login(BaseApi):
    """Login Processing - API Interface Classes"""

    api_name = "login"

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

    def authenticate2(self, json) -> AuthenticateResult:
        """Synchronized Login Interface

        :param json: login parameters
            {
            "loginname": "string",
            "password": "string",
            "systemtype": "string", }
            }
        :return: Login Result
"""

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

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

Add prompt handling for the login process as shown in the code below.

    def on_login(self, event):
        ()

    def LoginSync(self):
        # print("Starting synchronized login")
        login_name = ()
        login_pwd = ()
        if login_name == "":
            MessageUtil.show_tips(self, "Please enter a user name!")
            return

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

        message = "Trying to log in to get a token, please wait..."
        icon = get_bitmap("appIcon", 16)
        busy = (message, parent=self, title="Logging in to process...", icon=icon)
        try:
            ()  # refresh screen

            result = api_login.authenticate2(json_data)
            if :
                # print("Login successful", result)
                self._accesstoken = 
                ApiClient.set_access_token()
                self.is_login = True
                ()
            else:
                MessageUtil.show_tips(self, "The username or password is incorrect!")
        except Exception as e:
            # print(e)
            MessageUtil.show_tips(
                self, "Login failed! The error message is as follows:", extended_message=str(e)
            )
        finally:
            # Close Cue Box
            del busy

After running the login, the interface prompts for information about getting the token

Jump to the main interface form on success.

The above is the actual use of wxpython to develop cross-platform desktop application login interface, docked back-end FastAPI WebAPI project, the project using FastAPI, SQLAlchemy, Pydantic, Pydantic-settings, Redis, JWT built projects, database access using asynchronous way! Database access is asynchronous. Database operations and controller operations , the use of base class inheritance to reduce duplication of code , to improve code reuse . Support for Mysql, Mssql, Postgresql, Sqlite and other database access , through the configuration can specify the database connection .