Location>code7788 >text

Design and Implementation of Parameter Configuration Management Interface for WxPython Cross-Platform Development Framework

Popularity:638 ℃/2024-12-10 17:23:58

I previously wrote about this in 2014 in the essay "TheWinform development framework of the parameter configuration management functional realization - based on the construction of theNET-based parameter configuration management interface, this essay is based on a similar effect, and introduces the use of the WxPython cross-platform development framework on theLabelBook control to realize the effect of the configuration management interface.

1. Review of the characteristics of the parameter configuration management interface and the .

The Parameter Configuration Management interface is characterized by the following features:

The interface is divided into sections according to different functional modules or parameter categories, commonly in the form of tabs.

Each module contains setup controls for related parameters, making it easy for users to quickly locate and modify specific settings.

The interface is logically clear and easy to maintain. Avoid over-centralization of information and improve readability.

Different types of parameters are involved, such as Boolean values (checkboxes), enumerated values (dropdown menus), numeric values (textboxes or sliders), paths (file selectors), etc. Depending on the purpose of the parameter, the appropriate control can be selected to enhance the user experience.

Provides the ability to save and load configurations to a file, database, or the cloud for easy multiple use and sharing.

A good parameter configuration management interface takes these characteristics into account, providing an efficient, intuitive and secure operating experience, while meeting the need for system scalability.

The Essay.Winform development framework of the parameter configuration management functional realization - based on the construction of theNET-based parameter configuration management function, as shown in the following interface.

It is implemented through a main form container, as shown below, the

The integration of individual panels is then provided to form a multi-panel configuration management interface.

 

2. Configuration management interface implementation based on the WxPython cross-platform development framework

In the WxPython Component Module, we can use the LabelBook control to implement the functionality of the configuration management interface.

LabelBook Yes, wxPython.AGW library is an enhanced tab control similar to the standard, but offers a richer appearance and functionality. Using it for the configuration management interface has the following advantages:

LabelBook be Part of the module.

Let's look at a simple use case as shown in the code below.

import wx
import  as LB
from  import *


class ConfigApp():
    def __init__(self, parent=None):
        super().__init__(parent, title="configuration management", size=(800, 600))

        # Creating a LabelBook Control
        panel = (self)
        labelbook = (panel, agwStyle=LB.INB_LEFT | INB_FIT_LABELTEXT)

        # Creating a Layout
        sizer = ()
        (labelbook, 1, )
        (sizer)

        # Adding a Configuration Page
        self.add_pages(labelbook)
        ()
        ()

    def add_pages(self, labelbook: ):

        # Creating a list of images
        self.image_list = (32, 32)
        self.image_list.Add(
            (wx.ART_NEW_DIR, wx.ART_OTHER, (32, 32))
        )
        self.image_list.Add(
            (wx.ART_ADD_BOOKMARK, wx.ART_OTHER, (32, 32))
        )
        self.image_list.Add(
            (wx.ART_CDROM, wx.ART_OTHER, (32, 32))
        )
        (self.image_list)

        # Example Page 1: Basic Settings
        page1 = (labelbook)
        (page1, label="Basic setup contents", pos=(20, 20))
        (page1, "Basic settings", select=True, imageId=0)

        # Example Page 2: Network Settings
        page2 = (labelbook)
        (page2, label="Network Setup Content", pos=(20, 20))
        (page2, "network setup", select=True, imageId=1)

        # Example Page 3: Advanced Settings
        page3 = (labelbook)
        (page3, label="Advanced Setting Contents", pos=(20, 20))
        (page3, "Advanced Settings", select=True, imageId=2)


if __name__ == "__main__":
    app = (False)
    frame = ConfigApp()
    ()
    ()

The simple interface effect is shown below.

Once we have a main structure, we can design their styles and the content of the panels. We can set its associated color effects with a function.

    def SetUserColours(self):
        """Setting LabelBook user-defined colors"""

         = (132, 164, 213)
         = (255, 255, 255)
         = (0, 0, 204)
         = (0, 0, 0)
         = (0, 0, 0)
         = (191, 216, 216)

        (INB_TAB_AREA_BACKGROUND_COLOUR, )
        (INB_ACTIVE_TAB_COLOUR, )
        (INB_TABS_BORDER_COLOUR, )
        (INB_TEXT_COLOUR, )
        (INB_ACTIVE_TEXT_COLOUR, )
        (INB_HILITE_TAB_COLOUR, )

We let the creation of each panel be created independently of a function, as shown below.

        # Add Page
        self.email_panel = self.create_email_panel()
        self.system_panel = self.create_system_panel()

        (self.email_panel, "Mailbox Configuration", True, imageId=0)
        (self.system_panel, "System settings", True, imageId=1)

Where the system setup is simple as shown below.

    def create_system_panel(self, parent):
        panel = (parent)
        sizer = ()

        # System parameter 1
        param1_sizer = ()
        param1_label = (panel, label="Parameter 1:")
        self.param1_input = (panel)
        param1_sizer.Add(param1_label, 0, wx.ALIGN_CENTER_VERTICAL | , 10)
        param1_sizer.Add(self.param1_input, 1,  | , 10)

        # System Parameter 2
        param2_sizer = ()
        param2_label = (panel, label="Parameter 2:")
        self.param2_input = (panel)
        param2_sizer.Add(param2_label, 0, wx.ALIGN_CENTER_VERTICAL | , 10)
        param2_sizer.Add(self.param2_input, 1,  | , 10)

        # Add to Panel
        (param1_sizer, 0, )
        (param2_sizer, 0, )

        (sizer)
        return panel

Through the above division, you can create a good corresponding interface control input and processing, the creation of the interface effect is shown below.

Since there may be many configuration pages, the handling of different business parameter settings may vary. We design a configuration interface base class:MyConfigDialog

Other business configuration classes can have default regular processing effects and implementations by inheriting from it, e.g. we have aFrmConfigSettings subclasses, the relationship diagram is shown below.

We just need to configure the interface base class againMyConfigDialogDefine the method to create the add page in the following, and leave it to the subclasses to implement it.

    def create_papges(self, parent: ):
        """Create Page - Subclass Override"""

If we subclassFrmConfigSettings The method to add a page is implemented as follows.

    def create_papges(self, parent: ):
        """Create Page - Subclass Override"""
        # Setting the image list
        image_list = (32, 32)
        image_list.Add(get_bitmap("email", 32))
        image_list.Add(get_bitmap("computer_key", 32))  # ART_INFORMATION
        image_list.Add(get_bitmap("book", 32))
        self.set_image_list(image_list)

        self.email_panel = self.create_email_panel()
        (self.email_panel, "Mailbox Configuration", True, imageId=0)

        self.env_panel = self.create_env_panel()
        (self.env_panel, "Application Information", False, imageId=1)

        self.params_panel = self.create_params_panel()
        (self.params_panel, "System Parameter Configuration", False, imageId=2)

We add the interface to introduce only defined auxiliary class GridBagUtil to simplify the addition of processing, the following code is to create a mailbox configuration interface.

    def create_email_panel(self, parent):
        """Creating a Mailbox Configuration Page"""
        panel = (parent, wx.ID_ANY)
        # Create a GridBagSizer
        grid_sizer = (2, 2)  # Row and column spacing of 5
        util = GridBagUtil(panel, grid_sizer, 4)

         = (panel)
        self.pop3_server = (panel)
        self.pop3_port = (panel)
        self.smtp_server = (panel)
        self.smtp_port = (panel)
         = (panel)
         = (panel, style=wx.TE_PASSWORD)
        self.user_ssl = (panel, label="Using SSL encryption")

        util.add_control("Mail Account", , is_expand=True, is_span=True, border=10)
        util.add_control("POP3 server:", self.pop3_server, is_expand=True, border=10)
        util.add_control("POP3 port number:", self.pop3_port, is_expand=True, border=10)
        util.add_control("SMTP server:", self.smtp_server, is_expand=True, border=10)
        util.add_control("SMTP port number:", self.smtp_port, is_expand=True, border=10)
        util.add_control( "Log in to your account:", , is_expand=True, is_span=True, border=10)
        util.add_control("Login Password:", , is_expand=True, is_span=True, border=10 )
        util.add_control("Whether SSL encryption:", self.user_ssl, is_expand=True, is_span=True, border=10)

        # Make the control stretch with the window
        grid_sizer.AddGrowableCol(1)  # Allow second column to stretch
        grid_sizer.AddGrowableCol(3)  # Allow third row to stretch
        (grid_sizer)
        ()
        return panel

The final interface effect is shown below.

Compare to the previous interface effect, the overall effect has its own flavor, right?

In the parameter configuration management interface for WxPython above, I designed several different parameter management, including the handling of ini files, the reading of .env configuration files, and the implementation of several different elements based on the system's parameter management interface in the backend database.

For example, for mailbox configuration information, we store it in an INI file, so it is sufficient to create a helper class for accessing the information in the INI file.

When displaying the data, the data is displayed by calling the auxiliary class, as follows is the read display function for the mail parameter.

    def display_email_data(self):
        """Displaying Mailbox Configuration Data"""
        # print()
        filepath =  + "/" + 
        ini_setting = IniSettingUtil(filepath)

        (ini_setting.get(, "email", ""))
        self.pop3_server.SetValue(ini_setting.get(, "pop3_server", ""))
        self.pop3_port.SetValue(ini_setting.get_int(, "pop3_port", 0))
        self.smtp_server.SetValue(ini_setting.get(, "smtp_server", ""))
        self.smtp_port.SetValue(ini_setting.get_int(, "smtp_port", 0))
        (ini_setting.get(, "username", ""))
        (ini_setting.get(, "password", ""))
        self.user_ssl.SetValue(ini_setting.get_bool(, "ssl", False))

The program's parameter information is loaded into the system's configuration class through Pydantic_Setting, so it can be read directly.

    def display_env_data(self):
        """Displaying application information data"""

        self.app_name.SetValue(settings.APP_NAME)
        self.app_version.SetValue(settings.APP_VERSION)
        self.app_desc.SetValue()
        self.app_baseapi.SetValue(settings.API_BASE_URL)
        self.app_unit.SetValue(settings.APP_UNIT)
        self.app_author.SetValue(settings.App_Author)
        self.app_email.SetValue(settings.App_Email)

A good way to understand how settings come about is to understand how Pydantic_Setting is handled, which is an instance of a parameter class that reads .env configuration parameters from the directory into the class to be handled as properties.

class Settings(BaseSettings):
    """System Information Configuration Class"""

    model_config = SettingsConfigDict(
        env_file=f"{BasePath}/.env",  # Loading env files
        extra="ignore",  # Load the env file and don't throw an exception if no properties are defined in Settings
        env_file_encoding="utf-8",
        env_prefix="",
        case_sensitive=False,
    )

    # Application information (project name, version, description, etc.), read from .env file
    APP_NAME: str = "wxpython-Project"
    APP_VERSION: str = "1.0.0"
    DESCRIPTION: str = "This project is a GUI application based on wxPython."
    API_BASE_URL: str = "http://localhost:8000/api/"
    APP_UNIT: str = "Guangzhou Aqidi Software Technology Co."  # Name of unit
    App_Author: str = "Ng Wah Chung (1974-), * actor"  # Project Author
    App_Email: str = ""  # Project Author Email

If .env does not have a value, then the default value here is used, and if it does, the parameter values in .env are loaded.

In addition, our system provides a common parameter management module, which can also be integrated for display.

This module is directly read remotely through the API to get the data to display.

    async def display_params_data(self):
        """Display parameter configuration data"""
        company_name = await api_systemparam.get_by_name("company identification")
        address = await api_systemparam.get_by_name("Company Address")
        contact = await api_systemparam.get_by_name("Company Contacts")
        invoice = await api_systemparam.get_by_name("Invoicing Information")

        self.param_company.SetValue(company_name.content)
        self.param_address.SetValue()
        self.param_contact.SetValue()
        self.param_invoice.SetValue()

Above is the idea and process we realized in doing WxPython cross-platform configuration management interface, through the way of abstract base class, to reduce the commonly used code and logic, and provide a good extension.