首页 > 编程语言 >WxPython跨平台开发框架之参数配置管理界面的设计和实现

WxPython跨平台开发框架之参数配置管理界面的设计和实现

时间:2024-12-10 11:22:57浏览次数:7  
标签:SetValue 界面 sizer self 配置管理 跨平台 WxPython wx panel

我曾经在2014年在随笔《Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建》介绍过基于.NET开发的参数配置管理界面,本篇随笔基于类似的效果,介绍在WxPython跨平台开发框架上使用LabelBook 控件实现配置管理界面的效果。

1、参数配置管理界面的特点和 .NET 实现回顾

参数配置管理界面的特点主要体现在以下几个方面:

界面按照不同的功能模块或参数类别划分为多个部分,常见形式包括选项卡。

每个模块包含相关参数的设置控件,便于用户快速定位和修改特定设置。

界面逻辑清晰,便于维护。避免信息过于集中,提高可读性。

涉及不同类型的参数,例如布尔值(复选框)、枚举值(下拉菜单)、数值(文本框或滑块)、路径(文件选择器)等。可根据参数的用途选择适当的控件以提高用户体验。

提供保存和加载配置的功能,将配置保存到文件、数据库或云端,便于多次使用和分享。

一个好的参数配置管理界面会综合考虑这些特点,提供高效、直观且安全的操作体验,同时满足系统可扩展性的需求。

随笔《Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建》介绍过基于.NET开发的参数配置管理功能,如下界面所示。

它的实现是通过一个主窗体容器,如下所示,

然后再提供各个面板的整合形成一个多面板的配置管理界面。

 

2、基于WxPython跨平台开发框架的配置管理界面实现

在WxPython组件模块中,我们可以使用 wx.lib.agw.labelbook 的 LabelBook 控件实现配置管理界面的功能。

LabelBook 是 wxPython AGW 库中的一个增强选项卡控件,类似于标准的 wx.Notebook,但提供了更丰富的外观和功能。使用它来实现配置管理界面有以下优势:

LabelBookwx.lib.agw.labelbook 模块的一部分。

我们来看看一个简单的使用案例,如下代码所示。

import wx
import wx.lib.agw.labelbook as LB
from wx.lib.agw.fmresources import *


class ConfigApp(wx.Frame):
    def __init__(self, parent=None):
        super().__init__(parent, title="配置管理", size=(800, 600))

        # 创建 LabelBook 控件
        panel = wx.Panel(self)
        labelbook = LB.LabelBook(panel, agwStyle=LB.INB_LEFT | INB_FIT_LABELTEXT)

        # 创建布局
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(labelbook, 1, wx.EXPAND)
        panel.SetSizer(sizer)

        # 添加配置页面
        self.add_pages(labelbook)
        self.Layout()
        self.SendSizeEvent()

    def add_pages(self, labelbook: LB.LabelBook):

        # 创建图像列表
        self.image_list = wx.ImageList(32, 32)
        self.image_list.Add(
            wx.ArtProvider.GetBitmap(wx.ART_NEW_DIR, wx.ART_OTHER, (32, 32))
        )
        self.image_list.Add(
            wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_OTHER, (32, 32))
        )
        self.image_list.Add(
            wx.ArtProvider.GetBitmap(wx.ART_CDROM, wx.ART_OTHER, (32, 32))
        )
        labelbook.AssignImageList(self.image_list)

        # 示例页面 1: 基础设置
        page1 = wx.Panel(labelbook)
        wx.StaticText(page1, label="基础设置内容", pos=(20, 20))
        labelbook.AddPage(page1, "基础设置", select=True, imageId=0)

        # 示例页面 2: 网络设置
        page2 = wx.Panel(labelbook)
        wx.StaticText(page2, label="网络设置内容", pos=(20, 20))
        labelbook.AddPage(page2, "网络设置", select=True, imageId=1)

        # 示例页面 3: 高级设置
        page3 = wx.Panel(labelbook)
        wx.StaticText(page3, label="高级设置内容", pos=(20, 20))
        labelbook.AddPage(page3, "高级设置", select=True, imageId=2)


if __name__ == "__main__":
    app = wx.App(False)
    frame = ConfigApp()
    frame.Show()
    app.MainLoop()

简单的界面效果如下所示。

 我们有一个主要的结构后,就可以设计它们的样式和面板的内容了。我们可以通过一个函数来设置它的相关颜色效果。

    def SetUserColours(self):
        """设置LabelBook用户自定义颜色"""

        self.background = wx.Colour(132, 164, 213)
        self.activetab = wx.Colour(255, 255, 255)
        self.tabsborder = wx.Colour(0, 0, 204)
        self.textcolour = wx.Colour(0, 0, 0)
        self.activetextcolour = wx.Colour(0, 0, 0)
        self.hilite = wx.Colour(191, 216, 216)

        self.book.SetColour(INB_TAB_AREA_BACKGROUND_COLOUR, self.background)
        self.book.SetColour(INB_ACTIVE_TAB_COLOUR, self.activetab)
        self.book.SetColour(INB_TABS_BORDER_COLOUR, self.tabsborder)
        self.book.SetColour(INB_TEXT_COLOUR, self.textcolour)
        self.book.SetColour(INB_ACTIVE_TEXT_COLOUR, self.activetextcolour)
        self.book.SetColour(INB_HILITE_TAB_COLOUR, self.hilite)

我们让每个面板的创建独立一个函数来创建,如下所示。

        # 添加页面
        self.email_panel = self.create_email_panel(self.book)
        self.system_panel = self.create_system_panel(self.book)

        self.book.AddPage(self.email_panel, "邮箱配置", True, imageId=0)
        self.book.AddPage(self.system_panel, "系统设置", True, imageId=1)

其中系统设置简单如下所示。

    def create_system_panel(self, parent):
        panel = wx.Panel(parent)
        sizer = wx.BoxSizer(wx.VERTICAL)

        # 系统参数1
        param1_sizer = wx.BoxSizer(wx.HORIZONTAL)
        param1_label = wx.StaticText(panel, label="参数1:")
        self.param1_input = wx.TextCtrl(panel)
        param1_sizer.Add(param1_label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)
        param1_sizer.Add(self.param1_input, 1, wx.EXPAND | wx.ALL, 10)

        # 系统参数2
        param2_sizer = wx.BoxSizer(wx.HORIZONTAL)
        param2_label = wx.StaticText(panel, label="参数2:")
        self.param2_input = wx.TextCtrl(panel)
        param2_sizer.Add(param2_label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)
        param2_sizer.Add(self.param2_input, 1, wx.EXPAND | wx.ALL, 10)

        # 添加到面板
        sizer.Add(param1_sizer, 0, wx.EXPAND)
        sizer.Add(param2_sizer, 0, wx.EXPAND)

        panel.SetSizer(sizer)
        return panel

通过上面的各司其职,就可以很好的创建对应的界面控件输入及处理了,创建的界面效果如下所示。

由于配置页面可能有很多个,不同的业务参数设置处理可能也有所不同。我们设计一个配置界面基类:MyConfigDialog

其他业务配置类,继承它即可具有默认的常规处理效果和实现,如我们有一个 FrmConfigSettings 的子类,关系图如下所示。

我们只需要再配置界面基类MyConfigDialog中定义创建添加页面的方法,留给子类实现即可,如下所示。

    def create_papges(self, parent: LB.LabelBook):
        """创建页面 - 子类重写"""

如我们在子类FrmConfigSettings 实现了添加页面的方法,如下所示。

    def create_papges(self, parent: LB.LabelBook):
        """创建页面 - 子类重写"""
        # 设置图像列表
        image_list = wx.ImageList(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.book)
        self.book.AddPage(self.email_panel, "邮箱配置", True, imageId=0)

        self.env_panel = self.create_env_panel(self.book)
        self.book.AddPage(self.env_panel, "应用程序信息", False, imageId=1)

        self.params_panel = self.create_params_panel(self.book)
        self.book.AddPage(self.params_panel, "系统参数配置", False, imageId=2)

我们添加界面引入只定义的辅助类GridBagUtil 来简化添加的处理,如下代码是创建一个邮箱配置的界面。

    def create_email_panel(self, parent):
        """创建邮箱配置页面"""
        panel = wx.Panel(parent, wx.ID_ANY)
        # 创建一个 GridBagSizer
        grid_sizer = wx.GridBagSizer(2, 2)  # 行间距和列间距为 5
        util = GridBagUtil(panel, grid_sizer, 4)

        self.email = ctrl.MyTextCtrl(panel)
        self.pop3_server = ctrl.MyTextCtrl(panel)
        self.pop3_port = ctrl.MyTextCtrl(panel)
        self.smtp_server = ctrl.MyTextCtrl(panel)
        self.smtp_port = ctrl.MyTextCtrl(panel)
        self.username = ctrl.MyTextCtrl(panel)
        self.password = ctrl.MyTextCtrl(panel, style=wx.TE_PASSWORD)
        self.user_ssl = ctrl.MyCheckBox(panel, label="使用SSL加密")

        util.add_control("邮件账号", self.email, is_expand=True, is_span=True, border=10)
        util.add_control("POP3服务器:", self.pop3_server, is_expand=True, border=10)
        util.add_control("POP3端口号:", self.pop3_port, is_expand=True, border=10)
        util.add_control("SMTP服务器:", self.smtp_server, is_expand=True, border=10)
        util.add_control("SMTP端口号:", self.smtp_port, is_expand=True, border=10)
        util.add_control( "登录账号:", self.username, is_expand=True, is_span=True, border=10)
        util.add_control("登录密码:", self.password, is_expand=True, is_span=True, border=10 )
        util.add_control("是否SSL加密:", self.user_ssl, is_expand=True, is_span=True, border=10)

        # 让控件跟随窗口拉伸
        grid_sizer.AddGrowableCol(1)  # 允许第二列拉伸
        grid_sizer.AddGrowableCol(3)  # 允许第三行拉伸
        panel.SetSizer(grid_sizer)
        panel.Layout()
        return panel

最终界面效果如下所示。

对比一下之前的界面效果,整体效果各有千秋吧。

上面的WxPython的参数配置管理界面中,我设计了几个不同的参数管理,包括对ini文件的处理,.env配置文件的读取,以及基于系统在后台数据库的参数管理界面实现多个不同内容的管理。

如对于邮箱的相关配置信息,我们存储在INI文件中,因此创建一个INI文件存取信息的辅助类来处理即可。

显示数据的时候,通过调用辅助类来实现数据的显示,如下是邮件参数的读取显示函数。

    def display_email_data(self):
        """显示邮箱配置数据"""
        # print(settings.AppDir)
        filepath = settings.AppDir + "/" + self.filepath
        ini_setting = IniSettingUtil(filepath)

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

而程序的相关参数信息,我们通过Pydantic_Setting的进行加载到系统的配置类中的,那么直接读取即可。

    def display_env_data(self):
        """显示应用程序信息数据"""

        self.app_name.SetValue(settings.APP_NAME)
        self.app_version.SetValue(settings.APP_VERSION)
        self.app_desc.SetValue(settings.DESCRIPTION)
        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)

关于settings是如何来的,可以了解一下Pydantic_Setting的处理方式,它是一个参数类的实例,可以读取目录下的.env配置参数到类里面作为属性处理。

class Settings(BaseSettings):
    """系统信息配置类"""

    model_config = SettingsConfigDict(
        env_file=f"{BasePath}/.env",  # 加载env文件
        extra="ignore",  # 加载env文件,如果没有在Settings中定义属性,也不抛出异常
        env_file_encoding="utf-8",
        env_prefix="",
        case_sensitive=False,
    )

    # 应用程序信息(项目名称、版本、描述等),从.env文件中读取
    APP_NAME: str = "wxpython-Project"
    APP_VERSION: str = "1.0.0"
    DESCRIPTION: str = "本项目是基于 wxPython 开发的 GUI 应用。"
    API_BASE_URL: str = "http://localhost:8000/api/"
    APP_UNIT: str = "广州爱奇迪软件科技有限公司"  # 单位名称
    App_Author: str = "伍华聪"  # 项目作者
    App_Email: str = ""  # 项目作者邮箱

如果.env没有值,那么就使用这里面的默认值,如有,则加载.env中的参数值。

另外,我们系统提供了一个常用的参数管理模块,也可以整合在其中进行显示。

这个模块直接是通过API进行远程读取获取数据显示的。

    async def display_params_data(self):
        """显示参数配置数据"""
        company_name = await api_systemparam.get_by_name("公司名称")
        address = await api_systemparam.get_by_name("公司地址")
        contact = await api_systemparam.get_by_name("公司联系人")
        invoice = await api_systemparam.get_by_name("开票信息")

        self.param_company.SetValue(company_name.content)
        self.param_address.SetValue(address.content)
        self.param_contact.SetValue(contact.content)
        self.param_invoice.SetValue(invoice.content)

以上就是我们在做WxPython跨平台的配置管理界面中,实现的思路和处理过程,通过抽象基类的方式,减少常用的代码和逻辑,并提供很好的扩展。

 

标签:SetValue,界面,sizer,self,配置管理,跨平台,WxPython,wx,panel
From: https://www.cnblogs.com/wuhuacong/p/18596781

相关文章

  • dbGate:一款功能强大且开源的跨平台数据库管理工具
    本文说的是一个支持多种数据库类型,包括但不限于MySQL、PostgreSQL、SQLServer、MongoDB、SQLite、Oracle、AmazonRedshift、CockroachDB以及MariaDB等。这使得你不需要为不同的数据库类型更换不同的管理工具,可以帮助你提高工作效率的神器!工具跨平台使用,可以在Windows、Linux、......
  • WxPython跨平台开发框架之表格数据导出到Excel并打开
    在Python中使用wxPython导出实体类列表数据到Excel,通常可以借助openpyxl或pandas库来实现。本篇随笔由浅入深,逐步介绍导出Excel文件的操作,然后结合跨平台项目的实现,根据抽象继承的方式,对不同业务模块的通用导出Excel文件功能,以及跨平台的打开处理方式的实现进行介绍。以......
  • 鸿蒙原生开发环境的创新与性能优化:从工具到跨平台支持的全方位提升
    鸿蒙原生开发环境的创新与性能优化:从工具到跨平台支持的全方位提升一、引言随着鸿蒙操作系统的不断发展,开发者对开发工具的要求也在逐渐提高。高效、智能的开发工具不仅能够帮助开发者快速实现创意,还能在开发过程中提供更好的支持和体验。本文将深入探讨鸿蒙原生开发中的......
  • WxPython跨平台开发框架之用户选择和标签组件的设计
    在系统的权限管理中,往往都会涉及到用户的选择处理,特别是基于角色的访问控制中,很多情况下需要用到选择用户的处理。本篇随笔,基于WxPython跨平台开发框架,采用原有开发框架成熟的一套权限系统理念,对机构、用户、角色、权限、菜单、日志、字典等内容进行管理的,因此也涉及到了用户选择......
  • 【结构专栏】solidworks零件的配置管理(configurationManager)技巧
    摘要:Solidworks的配置管理可以在一个装配中实现不同的状态,而且可以直接同步到工程图中,减少工作量。在装配中显示一个零件的不同配置,可以通过添加配置并在配置中添加或修改特征实现。配置管理也可以用于关联多个配置的零件,使其在工程图中显示不同的配置选项。转载自:https://baiji......
  • python:wxpython create mdi
     importwxclassMainFrame(wx.MDIParentFrame):def__init__(self,parent,title):wx.MDIParentFrame.__init__(self,parent,-1,title)#Createamenubarmenubar=wx.MenuBar()fileMenu=wx.Menu()newChildI......
  • C#WinForm实操串口通讯使用GtkSharp库实现跨平台
     Linux下运行.NET项目:1、环境安装2、cd项目路径3、dotnet项目dll,即可运行 部分代码分享:usingGtk;usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Refl......
  • [C#] 对24位图像进行水平翻转(FlipX)的跨平台SIMD硬件加速向量算法(使用YShuffleX3Kern
    在上一篇文章里,给大家讲解了32位图像水平翻转(FlipX)算法,于是本文来探讨更加复杂的24位图像水平翻转算法。本文除了会给出标量算法外,还会给出向量算法。且这些算法是跨平台的,同一份源代码,能在X86(Sse、Avx等指令集)及Arm(AdvSimd等指令集)等架构上运行,且均享有SIMD硬件加速。一、标......
  • [C#] 对24位图像进行水平翻转(FlipX)的跨平台SIMD硬件加速向量算法(使用YShuffleX3Kern
    在上一篇文章里,给大家讲解了32位图像水平翻转(FlipX)算法,于是本文来探讨更加复杂的24位图像水平翻转算法。本文除了会给出标量算法外,还会给出向量算法。且这些算法是跨平台的,同一份源代码,能在X86(Sse、Avx等指令集)及Arm(AdvSimd等指令集)等架构上运行,且均享有SIMD硬件加速。一、标......
  • [C#] 对24位图像进行水平翻转(FlipX)的跨平台SIMD硬件加速向量算法(使用YShuffleX3Kern
    在上一篇文章里,给大家讲解了32位图像水平翻转(FlipX)算法,于是本文来探讨更加复杂的24位图像水平翻转算法。本文除了会给出标量算法外,还会给出向量算法。且这些算法是跨平台的,同一份源代码,能在X86(Sse、Avx等指令集)及Arm(AdvSimd等指令集)等架构上运行,且均享有SIMD硬件加速。一、标......