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
模块的一部分。
我们来看看一个简单的使用案例,如下代码所示。
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跨平台的配置管理界面中,实现的思路和处理过程,通过抽象基类的方式,减少常用的代码和逻辑,并提供很好的扩展。
WxPython跨平台开发框架之参数配置管理界面的设计和实现的更多相关文章
- Production环境中iptables常用参数配置
production环境中iptables常用参数配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我相信在实际生产环境中有很多运维的兄弟跟我一样,很少用到iptables的这个 ...
- Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建
在较早时期,我写过一篇文章<结合Control.FirefoxDialog控件,构造优秀的参数配置管理模块>,介绍过在我的Winform框架基础上集成的参数配置模块功能,但是参数模块的配置 ...
- [ionic开源项目教程] - 手把手教你使用移动跨平台开发框架Ionic开发一个新闻阅读APP
前言 这是一个系列文章,从环境搭建开始讲解,包括网络数据请求,将持续更新到项目完结.实战开发中遇到的各种问题的解决方案,也都将毫无保留的分享给大家. 关注订阅号:TongeBlog ,查看移动端跨平台 ...
- 移动跨平台开发框架Ionic开发一个新闻阅读APP
移动跨平台开发框架Ionic开发一个新闻阅读APP 前言 这是一个系列文章,从环境搭建开始讲解,包括网络数据请求,将持续更新到项目完结.实战开发中遇到的各种问题的解决方案,也都将毫无保留的分享给大家. ...
- HttpClient 4.3连接池参数配置及源码解读
目前所在公司使用HttpClient 4.3.3版本发送Rest请求,调用接口.最近出现了调用查询接口服务慢的生产问题,在排查整个调用链可能存在的问题时(从客户端发起Http请求->ESB-&g ...
- echarts画饼环状饼图相关参数配置
今天做页面的时候用到了环状饼图,大家都知道echarts的API文档看起来实在费劲,折腾了半天才画出来我想要的饼图,把我用到的参数配置分享给大家,希望能帮到和我一样的对echarts不是那么熟悉的童鞋 ...
- 性能测试 Apache参数配置与性能调优
Apache性能调优 by:授客 QQ:1033553122 环境: Apache 2.4 1.选择合适的MPM(Multi -Processing Modules, 多处理模块) Unix/Linu ...
- golang学习笔记8 beego参数配置 打包linux命令
golang学习笔记8 beego参数配置 打包linux命令 参数配置 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/docs/mvc/contro ...
- qt configure参数配置介绍
======================================全文是按照./configure -help来翻译的==================================== ...
- logback 常用参数配置详解
logback 常用配置详解(二) <appender> <appender>: <appender>是<configuration>的子节点,是负责写 ...
随机推荐
- 26岁女生转行车载测试1年,月入15K~
年前有朋友找工作,跟我说简历改了车载后,收到的打招呼翻了几倍,如今车载测试前景非常广阔,因为越来越多的汽车厂商正在开发新的可智能化的汽车,他们需要测试这些汽车的性能,安全性以及可靠性.车载测试技术可以 ...
- PS安装插件提示无法加载扩展未正确签署 的解决办法
PS安装插件提示无法加载扩展未正确签署解决方式 win系统: 1.打开"运行"窗口(点击电脑左下角"开始"菜单,从打开的菜单中依次点击"所有程序&qu ...
- 五行强度得分_喜用神api免费接口_json数据八字五行强弱接口
本API接口基于深厚的八字学原理,为用户提供详尽的五行(金.木.水.火.土)强弱分析.五行打分评估,以及精准的喜用神判断.用户只需输入自己的八字信息,即可获得全面而深入的命理解读. 一.核心功能 ...
- Pytorch 基于加权平滑过渡的无缝拼接
基于加权平滑过渡的无缝拼接 背景 在做照片数字人视频生成的时候,为了达到快速响应实时播放的需求,即视频的生成速度 必须小于 音频的播放速度. 因此,我们截取了一部分较小的可动区域进行推理生成,然后把生 ...
- 2022年10月中国数据库排行榜:达梦冲刺IPO热度不减,PolarDB立足创新夺锦才
秋风萧瑟,洪波涌起. 2022年10月的 墨天轮中国数据库流行度排行榜 火热出炉,本月共有245个数据库参与排名,相比上月新增七个数据库,本月排行榜前十名变动较大:达梦反超openGauss重摘探花: ...
- 墨天轮最受DBA欢迎的数据库技术文档-容灾备份篇
在大家的支持与认可下,墨天轮编辑部继续为大家整理出了[墨天轮最受欢迎的技术文档]系列第二篇--容灾备份篇,希望能够帮助到大家. 作为一名数据库管理员,最怕数据库中心突然失去服务能力.影响业务,而不论是 ...
- 小程序按住选中 text
<text selectable>按住选中可以赋值的</text>
- kotlin类与对象——>嵌套类与内部类、枚举类
1.嵌套类,类可以嵌套在其他类中: class Outer { private val bar: Int = 1 class Nested { fun foo() = 2 } } val demo = ...
- 云原生周刊:KubeSphere 宣布开源 Thanos 的企业级发行版 Whizard
开源项目推荐 Admiralty Admiralty 是一个 Kubernetes 控制器系统,可以智能地在多个集群之间调度工作负载.它使用简单,并且易于与其他工具集成. Cozystack Cozy ...
- Solution of CF1842C
Brief description of the title 若 \(a_i=a_j\) 且 \(1\le i < j\le |a|\).则删除 \(a_{i}\) 到 \(a_j\) 所有数. ...