- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
我曾经在2014年在随笔《Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建》介绍过基于.NET开发的参数配置管理界面,本篇随笔基于类似的效果,介绍在WxPython跨平台开发框架上使用LabelBook 控件实现配置管理界面的效果.
随笔《Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建》介绍过基于.NET开发的参数配置管理功能,如下界面所示.
它的实现是通过一个主窗体容器,如下所示, 。
然后再提供各个面板的整合形成一个多面板的配置管理界面.
。
在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跨平台开发框架之参数配置管理界面的设计和实现的文章就讲到这里了,如果你想了解更多关于WxPython跨平台开发框架之参数配置管理界面的设计和实现的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一家小型非营利组织的技术总监,我们正在制作一个新网站。我们提出了几个不同主页设计的模型,需要接收董事会成员的意见。是否有在线应用程序/程序/框架可以接收和组织用户评论?我正在寻找允许在查看页面时发
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我阅读了很多关于 java 接口(interface)的文章。我知道你可以实现多态性和其他伟大的东西(函数指针等)。我有理论知识,但有一点点或什至没有。我一直在使用很多已经制作好的界面,比如“Runn
已关闭。此问题旨在寻求有关书籍、工具、软件库等的建议。不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以
我正在尝试在 Windows 7 上编写一个 python 脚本来与我的 Wacom Bamboo Pen 数位板交互。 Wacom 建议使用 WinTab API,它工作正常,但不适用于我的应用程序
我正在研究一种远程访问有关 Linux 服务器统计信息的方法,即 conky会显示。 有没有办法与 conky 交互并获取它显示的统计信息?如果没有,您能否推荐一种获取此类统计数据的好方法? (C/C
将所有这些代码包装在 UI: do { } block 中的原因是什么?我在哪里可以获得关于它的明确说明? UI: do { backgroundButton.setImage(UIImage
我需要将 R 连接到某些 C# 应用程序。我安装了 rscproxy_1.3 和 R_Scilab_DCOM3.0-1B5 添加了对 STATCONNECTORCLNTLib、StatConnecto
我正在尝试遍历接口(interface)片段以通过 id 查找我的特定结构并更改属性。 type A struct { ID ID Steps []Step } type Ste
我有两种不同格式的相同界面,一种是键由低破折号分隔的 JSON 格式,另一种是 javascript camelCase 格式: JSON 格式: interface MyJsonInterface
操作系统:Linux。 我正在尝试寻找可能的方法来为我的嵌入式系统实现 Web 界面。 目前有一个外壳(基于文本)和一小组命令用于查询设备。 我是网络开发新手,我的问题是: 我必须使用什么网络服务器?
我正在尝试运行基于 Mechanical Turk Qualtrics 的调查,并且需要一些似乎可以通过 Mechanical Turk API 使用的功能,例如 custom Qualificati
我见过漂亮的 MetroTwit 界面 http://www.metrotwit.com/ ;我想知道使用了哪些 WPF 组件来尝试重现它。 最佳答案 MetroTwit 设计师在这里:) 所有的控件
我有一个小问题。我需要将 Hadoop Web 界面与我们的 Web 应用程序集成。我只需要一个 Hadoop 接口(interface),我们可以在其中运行一些 hadoop 命令,例如 1
假设我有这个 JavaScript 函数: function updateMainBuff(buff) { // do some stuff } 我的
我试图找出一个窗口是否属于当前的虚拟桌面。 我从 winapi 中找到了 VirtualDesktopManager 类,但即使根据 here 它应该位于“shobjidl.h” header 中,当
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 8年前关闭。 Improve this
我的 Tkinter GUI 界面有问题。文本不会在 shell 中打印,但如果将 Entry 放置在第一个 tk 窗口 get() 中,它就可以工作...帮助我吗? 这是我的代码: import o
我有一个在 MATLAB 中实现的随机微分方程组。只有 4 个变量与 Euler-Maruyama 集成,所以没有什么太花哨的......不过,技术细节对于这个问题并不重要。 您建议我如何构建一个 W
对于我创建的插件,我想添加一个网络界面,您可以从中更改设置并执行一些简单的数据操作。此数据操作应通过 sqlquerys 完成。我正在使用 sqlite 数据库,这就是问题开始的地方: 网站(serv
我是一名优秀的程序员,十分优秀!