在经过长时间对WxPython的深入研究,并对其构建项目有深入的了解,以及完成对基础框架的完整改写后,终于在代码生成工具完全整合了基于 Python 跨平台方案项目的代码快速生成了,包括基于FastApi 的后端Web API项目,以及前端的WxPython前端界面项目。本篇随笔主要介绍跨平台WxPython项目的前端代码生成内容。

1、代码生成工具的整合处理

在前面随笔《基于SqlAlchemy+Pydantic+FastApi的Python开发框架 》中提到过,对于基于FastApi的项目我们已经使用自家的代码生成工具快速进行代码的生成,FastApi+SqlAlchemy+Python后端代码生成,可以生成模型、Schema对象、CRUD封装类、Endpoint路由类等。

本次在基于对WxPython的深入研究,并对我基础框架的内容进行全部的改写后,整理了基于WxPython的项目代码生成,其中包括生成列表界面、新增/编辑界面、WebApi调用类、实体信息等。对WxPython跨平台项目界面的有兴趣的可以参考随笔《分享一个纯Python开发的系统程序,基于VSCode + WxPython开发的跨平台应用系统》。

至此,整个Python的项目前后端串联起来,完成了一个完整的项目了。

代码生成工具可以到地址下载:https://www.iqidi.com/database2sharp.htm,使用代码生成工具来快速开发项目代码,有很多好处。

减少重复工作:自动生成常用代码(如数据模型、CRUD 操作、API 接口等),减少手动编写的时间。

专注于核心逻辑:开发者可以将时间集中在业务逻辑和复杂问题的解决上,而非基础代码的编写。

模块化和规范化:生成代码一般遵循既定的架构和风格,便于后续维护和扩展。

初学者友好:新手开发者可以通过代码生成工具快速上手,了解项目结构和基础代码。

代码生成工具在提升开发效率、降低出错率、标准化代码方面具有显著优势,尤其在重复性工作较多或团队合作时尤为适用。

1)后端项目代码的生成

Python + FastAPI项目是一个Web API的项目,为各个前端提供接口的后端项目,其界面自动整合Swagger的文档界面,如下所示。

在代码生成工具打开数据库列表后,右键菜单可以选择生成对应的Python+FastApi后端项目,如下界面所示。

选中相关的表后,一键可以生成各层的类文件,其中包括最为繁琐的Model映射类信息。如下是生成的相关类的界面效果。

2) WxPython前端项目代码生成

在经过对WxPython的深入研究后,并依据改造过的项目结构,整合在代码生成工具中,对项目的代码,包括列表界面,编辑界面、API调用类、DTO实体信息等进行统一的生成。

选择相关的数据表后,一键生成相关的代码,如下所示。

1)列表界面和继承关系

列表界面继承基类,从而可以大幅度的利用相应的规则和实现。

如对于两个例子窗体:系统类型定义,客户信息,其中传如对应的DTO信息和参数即可。

因为常规的列表界面一般分为查询区、列表界面展示区和分页信息区,我们把它分为两个主要的部分,如下界面所示。

当然如果有树形列表的,也整合在基类窗体中实现控制逻辑,具体实现放在子类处理即可。

同时,在树列表或者表格数据控件支持右键弹出菜单处理,包括常规的新增、编辑、删除、复制、刷新等常规功能,如果需要更多业务模块的功能,整合在右键菜单中,在窗体子类中重写某些只定义函数即可实现。

对于列表界面,生成的代码如下所示(以客户信息表为例):

代码工具最大程度的提供常规方法的处理,如果需要特殊的操作,如在查询框中的条件,那么需要根据需要修改一下即可。

    def CreateConditions(self, pane: wx.Window) -> List[wx.Window]:
"""创建折叠面板中的查询条件输入框控件"""
# 创建控件,不用管布局,交给CreateConditionsWithSizer控制逻辑
# 默认的FlexGridSizer为4*2=8列,每列间隔5px
self.txtName = ctrl.MyTextCtrl(pane)
self.txtAge = ctrl.MyNumericRange(pane)
self.txtCustomerType = ctrl.MyComboBox(pane, style=wx.CB_READONLY) util = ControlUtil(pane)
util.add_control("姓名:", self.txtName)
util.add_control("年龄:", self.txtAge)
util.add_control("客户类型:", self.txtCustomerType) # 测试数据类型绑定 return util.get_controls()

基本上就是不变的内容和规则,由基类处理,变化的内容,由子类来具体化即可。对于新增、编辑、删除的操作,我们根据表的不同,生成子类实现代码,一般不用修改。

    async def OnAdd(self, event: wx.Event) -> None:
"""子类重写-打开新增对话框"""
dlg = FrmCustomerEdit(self)
if await AsyncShowDialogModal(dlg) == wx.ID_OK:
# 新增成功,刷新表格
await self.update_grid()
dlg.Destroy()

如果需要再查询框中初始化下拉列表的内容,我们重写初始化字典函数即可。

    async def init_dict_items(self):
"""初始化字典数据-子类重写"""
await self.txtCustomerType.bind_dictType("客户类型")

通过上面我们构建的基类处理,以及提供一个界面辅助类来处理,可简化很多不必要的代码,而且还很灵活的控制布局处理,非常方便。

2)编辑/新增界面继承关系

继承基类编辑对话框(通常用于创建模态对话框或自定义窗口的基类)有以下优点:

  • 共享通用功能:将所有对话框的共同行为(如按钮布局、事件处理、数据校验逻辑等)封装在基类中,子类可以直接继承使用,无需重复实现。
  • 减少冗余代码:对话框的通用结构只需在基类中实现一次,后续的功能扩展只需通过继承来实现,减少代码重复。
  • 统一界面风格:基类可以预定义窗口的样式和布局,确保项目中所有对话框的界面一致。
  • 快速定制功能:子类仅需实现或覆盖特定方法,即可快速实现自定义对话框的功能。

继承基类编辑对话框能够提高代码复用性、开发效率和维护性,特别适合在复杂系统中管理多个相似对话框。通过合理设计基类,开发者可以显著减少重复代码,实现更灵活的功能扩展。

常规的对话框中,业务表编码规则的新增、编辑界面如下所示。

当然,我们也可以增加更多的定制功能,稍作调整可以增加多页的功能。

一般我们在编辑框中,或者列表窗体中,我们都可能有树形列表的情况,我们提供标准的处理方法,用于对这些内容进行修改。

对于编辑界面来说,我们继承父类后,子类重写一些实现函数即可实现弹性化的处理了。

上面这些函数就是各司其职,对界面的内容处理,显示编辑数据,校验输入,初始化字典、加载信息,保存对象信息,都是我们在编辑框中需要处理到的内容,我们根据不同的需求进行修改即可。

生成的界面代码中,对于输入控件的显示放在add_controls函数里面,如下代码所示。

    def add_controls(self, panel: wx.Window) -> wx.GridBagSizer:
# 创建一个 GridBagSizer
grid_sizer = wx.GridBagSizer(5, 5) # 行间距和列间距为 5
util = GridBagUtil(panel, grid_sizer, 2) # 构建工具类,布局为2列 self.txtName = ctrl.MyTextCtrl(panel, placeholder="客户姓名")
self.txtAge = wx.SpinCtrl(panel)
self.txtCreateTime = ctrl.MyDatePickerCtrl(panel)
self.txtCreateTime.Disable() self.txtNote = ctrl.MyTextCtrl(panel, placeholder="备注", style=wx.TE_MULTILINE) util.add_control("客户姓名", self.txtName, is_expand=True)
util.add_control("年龄", self.txtAge, is_expand=True)
util.add_control("创建日期", self.txtCreateTime, is_expand=True)
util.add_control("备注", self.txtNote, is_expand=True, is_span=True) # 让控件跟随窗口拉伸
grid_sizer.AddGrowableCol(1) # 允许第n列拉伸
return grid_sizer

我们通过代码

util = GridBagUtil(panel, grid_sizer, 2) # 构建工具类,布局为2列

构建了一个辅助类来处理布局的,添加的时候不用管布局,大概知道是几列的即可。

在Windows下,客户信息的编辑界面如下所示。

如果我们需要修改为双排的,那么修改下:

    def add_controls(self, panel: wx.Window) -> wx.GridBagSizer:
# 创建一个 GridBagSizer
grid_sizer = wx.GridBagSizer(5, 5) # 行间距和列间距为 5
util = GridBagUtil(panel, grid_sizer, 4) # 构建工具类,布局为4列 self.txtName = ctrl.MyTextCtrl(panel, placeholder="客户姓名")
self.txtAge = wx.SpinCtrl(panel)
self.txtCreateTime = ctrl.MyDatePickerCtrl(panel)
self.txtCreateTime.Disable() self.txtNote = ctrl.MyTextCtrl(panel, placeholder="备注", style=wx.TE_MULTILINE) util.add_control("客户姓名", self.txtName, is_expand=True)
util.add_control("年龄", self.txtAge, is_expand=True)
util.add_control("创建日期", self.txtCreateTime, is_span=True)
util.add_control("备注", self.txtNote, is_expand=True, is_span=True, is_stretch=True) # 让控件跟随窗口拉伸
grid_sizer.AddGrowableCol(1) # 允许第n列拉伸
grid_sizer.AddGrowableCol(3) # 允许第n列拉伸
return grid_sizer

界面效果如下所示。

稍作修改即可重新布局,非常方便。

利用代码生成工具,可以很好的利用现有基类的关系生成相关的代码,包括界面代码,对Web API的调用代码也是一样,我们只需要做好继承关系,就具有基类一些的CRUD接口了。

例如对于客户信息的API接口封装类,我们只需要增加一些个性化的自定义函数即可,默认对应基类有相关的CRUD接口。

class Customer(BaseApi[CustomerDto]):
"""客户信息--API接口类""" api_name = "customer" def __init__(self):
super().__init__(self.api_name, CustomerDto) async def exist(self, name: str = None, id: str = None) -> bool:
"""判断记录是否存在,如果指定ID,则判断ID不等于当前ID的记录是否存在"""
url = f"{self.base_url}/exist"
params = {"name": name, "id": id}
data = await self.client.get(url, params=params) res = AjaxResponse[bool].model_validate(data)
return res.result if res.success else False async def get_by_name(self, name: str) -> CustomerDto:
"""根据名称获取客户信息"""
url = f"{self.base_url}/by-name"
params = {"name": name}
data = await self.client.get(url, params=params) res = AjaxResponse[CustomerDto].model_validate(data)
return res.result if res.success else None # 构建一个业务逻辑实例,方便调用
api_customer = Customer()

这个基类的函数,和后端的控制器接口一一对应。

利用代码生成工具,开发项目事半功倍,这就是工具的力量和魅力。

在自家的代码生成工具中,增加对跨平台WxPython项目的前端代码生成,简直方便的不得了的更多相关文章

  1. 利用代码生成工具Database2Sharp生成ABP VNext框架项目代码

    我们在做某件事情的时候,一般需要详细了解它的特点,以及内在的逻辑关系,一旦我们详细了解了整个事物后,就可以通过一些辅助手段来提高我们的做事情的效率了.本篇随笔介绍ABP VNext框架各分层项目的规则 ...

  2. 基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发

    我喜欢在一个项目开发模式成熟的时候,使用代码生成工具Database2Sharp来配套相关的代码生成,对于我介绍的基于SqlSugar的开发框架,从整体架构确定下来后,我就着手为它们量身定做相关的代码 ...

  3. 基于Metronic的Bootstrap开发框架经验总结(18)-- 在代码生成工具Database2Sharp中集成对Bootstrap-table插件的分页及排序支持

    在我们开发系统界面,包括Web和Winform的都一样,主要的界面就是列表展示主界面,编辑查看界面,以及一些辅助性的如导入界面,选择界面等,其中列表展示主界面是综合性的数据展示界面,一般往往需要对记录 ...

  4. C#反射实现 C# 反射 判断类的延伸类型 使用代码生成工具Database2Sharp快速生成工作流模块控制器和视图代码 C# ADO.NET的SqlDataReader对象,判断是否包含指定字段 页面中添加锚点的几种方式 .net 简单实用Log4net(多个日志配置文件) C# 常用小点

    C#反射实现   一.反射概念: 1.概念: 反射,通俗的讲就是我们在只知道一个对象的内部而不了解内部结构的情况下,通过反射这个技术可以使我们明确这个对象的内部实现. 在.NET中,反射是重要的机制, ...

  5. 在代码生成工具Database2Sharp中使用ODP.NET(Oracle.ManagedDataAccess.dll)访问Oracle数据库,实现免安装Oracle客户端,兼容32位64位Oracle驱动

    由于我们开发的辅助工具Database2Sharp需要支持多种数据库,虽然我们一般使用SQLServer来开发应用较多,但是Oracle等其他数据库也是常用的数据库之一,因此也是支持使用Oracle等 ...

  6. 使用代码生成工具Database2Sharp快速生成工作流模块控制器和视图代码

    在前面随笔<基于Metronic的Bootstrap开发框架--工作流模块功能介绍>和<基于Metronic的Bootstrap开发框架--工作流模块功能介绍(2)>中介绍了B ...

  7. 基于SqlSugar的开发框架循序渐进介绍(21)-- 在工作流列表页面中增加一些转义信息的输出,在后端进行内容转换

    有时候,为了给前端页面输出内容,有时候我们需要准备和数据库不一样的实体信息,因为数据库可能记录的是一些引用的ID或者特殊字符,那么我们为了避免前端单独的进行转义处理,我们可以在后端进行统一的格式化后再 ...

  8. 如何在BI中增加“路线地图”并进行数据分析?

    随着客户的需求越来越"百变",最近在做大屏设计的葡萄陷入了困境. 近期客户提出的需求是想在BI工具中增加 "路线地图"展示功能并进行数据分析. 不仅如此,这个& ...

  9. git项目创建及在idea工具中使用

    1.安装git管理工具 2.在自己github账号上创建一个项目仓库,比如我创建的是renrenView 网页翻译如下: 参数解析如下: 3.本地项目同步到远程仓库步骤 在本地初始化git项目 git ...

  10. 代码生成工具Database2Sharp中增加视图的代码生成以及主从表界面生成功能

    在代码生成工具的各种功能规划中,我们一向以客户的需求作为驱动,因此也会根据需要增加一些特殊的功能或者处理.在实际的开发中,虽然我们一般以具体的表进行具体业务开发,但是有些客户提出有时候视图开发也是很常 ...

随机推荐

  1. 坑人的opencv安装

    我想捡起来C++,最近在看opencv,于是我想着一起吧. 但是我低估了这个小麻烦的魅力,曾经安装opencv c++版本就头秃,如今依然头秃.说明我没长进啊-- 折腾了两天,终于装上了. 其中最麻烦 ...

  2. 以太坊Rollup方案之 arbitrum(1)

    什么是Rollup? 以太坊的Rollup扩容是一种Layer 2(第二层)扩容解决方案,旨在提高以太坊区块链的交易吞吐量和性能.它通过将大量的交易数据转移到以太坊区块链之外的第二层网络来实现这一目标 ...

  3. 支付宝携手HarmonyOS SDK打造高效便捷的扫码支付体验

    背景 在日常的购物转账.生活缴费等在线支付中,用户在正式拉起支付界面前,均需要至少经历一次"识别"+两次"寻找",即识别归属应用.寻找应用.寻找扫码入口,才能完 ...

  4. TypeScript – Work with JavaScript Library (using esbuild)

    前言 JavaScript 早期是没有 Modular 和 Type (类型) 的. 随着这几年的普及, 几乎有维护的 Library 都有 Modular 和 Type 了. 但万一遇到没有 Mod ...

  5. Hugging Face NLP课程学习记录 - 2. 使用 Hugging Face Transformers

    Hugging Face NLP课程学习记录 - 2. 使用 Hugging Face Transformers 说明: 首次发表日期:2024-09-19 官网: https://huggingfa ...

  6. C#/.NET/.NET Core技术前沿周刊 | 第 6 期(2024年9.16-9.22)

    前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...

  7. Windows系统无法打开‘’网络发现‘’功能

    Windows10无法开启网络发现 解决办法: 1. services.msc 2. 开启 SSDP Discovery ,设置 启动类型为 自动 ,服务状态为 启动 Windows7 无法开启网络发 ...

  8. Android Qcom USB Driver学习(一)

    该系列文章总目录链接与各部分简介: Android Qcom USB Driver学习(零) USB接口类型 Android终端上常用的USB接口:TypeC(现在的主流),MicroB(以前的设备) ...

  9. NET Core 基础 - 删除字符串最后一个字符的七大类N种实现方式

    今天想通过和大家分享如何删除字符串最后一个字符的N种实现方法,来回顾一些基础知识点. 01.第一类.字符串方式 这类方法是通过string类型自身方法直接实现. 1.Substring方法 相信大多数 ...

  10. dotnet实现多态的三种方法

    虚方法 virual 抽象方法 abstract 不能 new  不带方法体: 接口 Interface