ToB企服应用市场:ToB评测及商务社交产业平台

标题: WxPython跨平台开发框架之参数设置管理界面的设计和实现 [打印本页]

作者: 星球的眼睛    时间: 2024-12-10 10:39
标题: WxPython跨平台开发框架之参数设置管理界面的设计和实现
我曾经在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,但提供了更丰富的外观和功能。使用它来实现设置管理界面有以下上风:
LabelBook 是 wx.lib.agw.labelbook 模块的一部分。
我们来看看一个简朴的使用案例,如下代码所示。
  1. import wx
  2. import wx.lib.agw.labelbook as LB
  3. from wx.lib.agw.fmresources import *
  4. class ConfigApp(wx.Frame):
  5.     def __init__(self, parent=None):
  6.         super().__init__(parent, title="配置管理", size=(800, 600))
  7.         # 创建 LabelBook 控件
  8.         panel = wx.Panel(self)
  9.         labelbook = LB.LabelBook(panel, agwStyle=LB.INB_LEFT | INB_FIT_LABELTEXT)
  10.         # 创建布局
  11.         sizer = wx.BoxSizer(wx.VERTICAL)
  12.         sizer.Add(labelbook, 1, wx.EXPAND)
  13.         panel.SetSizer(sizer)
  14.         # 添加配置页面
  15.         self.add_pages(labelbook)
  16.         self.Layout()
  17.         self.SendSizeEvent()
  18.     def add_pages(self, labelbook: LB.LabelBook):
  19.         # 创建图像列表
  20.         self.image_list = wx.ImageList(32, 32)
  21.         self.image_list.Add(
  22.             wx.ArtProvider.GetBitmap(wx.ART_NEW_DIR, wx.ART_OTHER, (32, 32))
  23.         )
  24.         self.image_list.Add(
  25.             wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_OTHER, (32, 32))
  26.         )
  27.         self.image_list.Add(
  28.             wx.ArtProvider.GetBitmap(wx.ART_CDROM, wx.ART_OTHER, (32, 32))
  29.         )
  30.         labelbook.AssignImageList(self.image_list)
  31.         # 示例页面 1: 基础设置
  32.         page1 = wx.Panel(labelbook)
  33.         wx.StaticText(page1, label="基础设置内容", pos=(20, 20))
  34.         labelbook.AddPage(page1, "基础设置", select=True, imageId=0)
  35.         # 示例页面 2: 网络设置
  36.         page2 = wx.Panel(labelbook)
  37.         wx.StaticText(page2, label="网络设置内容", pos=(20, 20))
  38.         labelbook.AddPage(page2, "网络设置", select=True, imageId=1)
  39.         # 示例页面 3: 高级设置
  40.         page3 = wx.Panel(labelbook)
  41.         wx.StaticText(page3, label="高级设置内容", pos=(20, 20))
  42.         labelbook.AddPage(page3, "高级设置", select=True, imageId=2)
  43. if __name__ == "__main__":
  44.     app = wx.App(False)
  45.     frame = ConfigApp()
  46.     frame.Show()
  47.     app.MainLoop()
复制代码
简朴的界面效果如下所示。

 我们有一个主要的布局后,就可以设计它们的样式和面板的内容了。我们可以通过一个函数来设置它的相干颜色效果。
  1.     def SetUserColours(self):
  2.         """设置LabelBook用户自定义颜色"""
  3.         self.background = wx.Colour(132, 164, 213)
  4.         self.activetab = wx.Colour(255, 255, 255)
  5.         self.tabsborder = wx.Colour(0, 0, 204)
  6.         self.textcolour = wx.Colour(0, 0, 0)
  7.         self.activetextcolour = wx.Colour(0, 0, 0)
  8.         self.hilite = wx.Colour(191, 216, 216)
  9.         self.book.SetColour(INB_TAB_AREA_BACKGROUND_COLOUR, self.background)
  10.         self.book.SetColour(INB_ACTIVE_TAB_COLOUR, self.activetab)
  11.         self.book.SetColour(INB_TABS_BORDER_COLOUR, self.tabsborder)
  12.         self.book.SetColour(INB_TEXT_COLOUR, self.textcolour)
  13.         self.book.SetColour(INB_ACTIVE_TEXT_COLOUR, self.activetextcolour)
  14.         self.book.SetColour(INB_HILITE_TAB_COLOUR, self.hilite)
复制代码
我们让每个面板的创建独立一个函数来创建,如下所示。
  1.         # 添加页面
  2.         self.email_panel = self.create_email_panel(self.book)
  3.         self.system_panel = self.create_system_panel(self.book)
  4.         self.book.AddPage(self.email_panel, "邮箱配置", True, imageId=0)
  5.         self.book.AddPage(self.system_panel, "系统设置", True, imageId=1)
复制代码
此中系统设置简朴如下所示。
  1.     def create_system_panel(self, parent):
  2.         panel = wx.Panel(parent)
  3.         sizer = wx.BoxSizer(wx.VERTICAL)
  4.         # 系统参数1
  5.         param1_sizer = wx.BoxSizer(wx.HORIZONTAL)
  6.         param1_label = wx.StaticText(panel, label="参数1:")
  7.         self.param1_input = wx.TextCtrl(panel)
  8.         param1_sizer.Add(param1_label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)
  9.         param1_sizer.Add(self.param1_input, 1, wx.EXPAND | wx.ALL, 10)
  10.         # 系统参数2
  11.         param2_sizer = wx.BoxSizer(wx.HORIZONTAL)
  12.         param2_label = wx.StaticText(panel, label="参数2:")
  13.         self.param2_input = wx.TextCtrl(panel)
  14.         param2_sizer.Add(param2_label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)
  15.         param2_sizer.Add(self.param2_input, 1, wx.EXPAND | wx.ALL, 10)
  16.         # 添加到面板
  17.         sizer.Add(param1_sizer, 0, wx.EXPAND)
  18.         sizer.Add(param2_sizer, 0, wx.EXPAND)
  19.         panel.SetSizer(sizer)
  20.         return panel
复制代码
通过上面的各司其职,就可以很好的创建对应的界面控件输入及处理了,创建的界面效果如下所示。

由于设置页面可能有许多个,不同的业务参数设置处理可能也有所不同。我们设计一个设置界面基类:MyConfigDialog
其他业务设置类,继承它即可具有默认的通例处理效果和实现,如我们有一个 FrmConfigSettings 的子类,关系图如下所示。

我们只需要再设置界面基类MyConfigDialog中定义创建添加页面的方法,留给子类实现即可,如下所示。
  1.     def create_papges(self, parent: LB.LabelBook):
  2.         """创建页面 - 子类重写"""
复制代码
如我们在子类FrmConfigSettings 实现了添加页面的方法,如下所示。
  1.     def create_papges(self, parent: LB.LabelBook):
  2.         """创建页面 - 子类重写"""        # 设置图像列表        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 来简化添加的处理,如下代码是创建一个邮箱设置的界面。
  1.     def create_email_panel(self, parent):
  2.         """创建邮箱配置页面"""
  3.         panel = wx.Panel(parent, wx.ID_ANY)
  4.         # 创建一个 GridBagSizer
  5.         grid_sizer = wx.GridBagSizer(2, 2)  # 行间距和列间距为 5
  6.         util = GridBagUtil(panel, grid_sizer, 4)
  7.         self.email = ctrl.MyTextCtrl(panel)
  8.         self.pop3_server = ctrl.MyTextCtrl(panel)
  9.         self.pop3_port = ctrl.MyTextCtrl(panel)
  10.         self.smtp_server = ctrl.MyTextCtrl(panel)
  11.         self.smtp_port = ctrl.MyTextCtrl(panel)
  12.         self.username = ctrl.MyTextCtrl(panel)
  13.         self.password = ctrl.MyTextCtrl(panel, style=wx.TE_PASSWORD)
  14.         self.user_ssl = ctrl.MyCheckBox(panel, label="使用SSL加密")
  15.         util.add_control("邮件账号", self.email, is_expand=True, is_span=True, border=10)
  16.         util.add_control("POP3服务器:", self.pop3_server, is_expand=True, border=10)
  17.         util.add_control("POP3端口号:", self.pop3_port, is_expand=True, border=10)
  18.         util.add_control("SMTP服务器:", self.smtp_server, is_expand=True, border=10)
  19.         util.add_control("SMTP端口号:", self.smtp_port, is_expand=True, border=10)
  20.         util.add_control( "登录账号:", self.username, is_expand=True, is_span=True, border=10)
  21.         util.add_control("登录密码:", self.password, is_expand=True, is_span=True, border=10 )
  22.         util.add_control("是否SSL加密:", self.user_ssl, is_expand=True, is_span=True, border=10)
  23.         # 让控件跟随窗口拉伸
  24.         grid_sizer.AddGrowableCol(1)  # 允许第二列拉伸
  25.         grid_sizer.AddGrowableCol(3)  # 允许第三行拉伸
  26.         panel.SetSizer(grid_sizer)
  27.         panel.Layout()
  28.         return panel
复制代码
最终界面效果如下所示。

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

上面的WxPython的参数设置管理界面中,我设计了几个不同的参数管理,包括对ini文件的处理,.env设置文件的读取,以及基于系统在后台数据库的参数管理界面实现多个不同内容的管理。
如对于邮箱的相干设置信息,我们存储在INI文件中,因此创建一个INI文件存取信息的辅助类来处理即可。

显示数据的时候,通过调用辅助类来实现数据的显示,如下是邮件参数的读取显示函数。
  1.     def display_email_data(self):
  2.         """显示邮箱配置数据"""
  3.         # print(settings.AppDir)
  4.         filepath = settings.AppDir + "/" + self.filepath
  5.         ini_setting = IniSettingUtil(filepath)
  6.         self.email.SetValue(ini_setting.get(self.section, "email", ""))
  7.         self.pop3_server.SetValue(ini_setting.get(self.section, "pop3_server", ""))
  8.         self.pop3_port.SetValue(ini_setting.get_int(self.section, "pop3_port", 0))
  9.         self.smtp_server.SetValue(ini_setting.get(self.section, "smtp_server", ""))
  10.         self.smtp_port.SetValue(ini_setting.get_int(self.section, "smtp_port", 0))
  11.         self.username.SetValue(ini_setting.get(self.section, "username", ""))
  12.         self.password.SetValue(ini_setting.get(self.section, "password", ""))
  13.         self.user_ssl.SetValue(ini_setting.get_bool(self.section, "ssl", False))
复制代码
而步调的相干参数信息,我们通过Pydantic_Setting的举行加载到系统的设置类中的,那么直接读取即可。
  1.     def display_env_data(self):
  2.         """显示应用程序信息数据"""
  3.         self.app_name.SetValue(settings.APP_NAME)
  4.         self.app_version.SetValue(settings.APP_VERSION)
  5.         self.app_desc.SetValue(settings.DESCRIPTION)
  6.         self.app_baseapi.SetValue(settings.API_BASE_URL)
  7.         self.app_unit.SetValue(settings.APP_UNIT)
  8.         self.app_author.SetValue(settings.App_Author)
  9.         self.app_email.SetValue(settings.App_Email)
复制代码

关于settings是如何来的,可以了解一下Pydantic_Setting的处理方式,它是一个参数类的实例,可以读取目录下的.env设置参数到类里面作为属性处理。
  1. class Settings(BaseSettings):
  2.     """系统信息配置类"""
  3.     model_config = SettingsConfigDict(
  4.         env_file=f"{BasePath}/.env",  # 加载env文件
  5.         extra="ignore",  # 加载env文件,如果没有在Settings中定义属性,也不抛出异常
  6.         env_file_encoding="utf-8",
  7.         env_prefix="",
  8.         case_sensitive=False,
  9.     )
  10.     # 应用程序信息(项目名称、版本、描述等),从.env文件中读取
  11.     APP_NAME: str = "wxpython-Project"
  12.     APP_VERSION: str = "1.0.0"
  13.     DESCRIPTION: str = "本项目是基于 wxPython 开发的 GUI 应用。"
  14.     API_BASE_URL: str = "http://localhost:8000/api/"
  15.     APP_UNIT: str = "广州爱奇迪软件科技有限公司"  # 单位名称
  16.     App_Author: str = "伍华聪"  # 项目作者
  17.     App_Email: str = ""  # 项目作者邮箱
复制代码
假如.env没有值,那么就使用这里面的默认值,如有,则加载.env中的参数值。

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

这个模块直接是通过API举行远程读取获取数据显示的。
  1.     async def display_params_data(self):
  2.         """显示参数配置数据"""
  3.         company_name = await api_systemparam.get_by_name("公司名称")
  4.         address = await api_systemparam.get_by_name("公司地址")
  5.         contact = await api_systemparam.get_by_name("公司联系人")
  6.         invoice = await api_systemparam.get_by_name("开票信息")
  7.         self.param_company.SetValue(company_name.content)
  8.         self.param_address.SetValue(address.content)
  9.         self.param_contact.SetValue(contact.content)
  10.         self.param_invoice.SetValue(invoice.content)
复制代码
以上就是我们在做WxPython跨平台的设置管理界面中,实现的思路和处理过程,通过抽象基类的方式,淘汰常用的代码和逻辑,并提供很好的扩展。
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4