我曾在随笔《基于Python后端构建多种不同的系统终端界面研究》介绍了多种系统终端界面开发的处理,其中涉及到的wxpython,是一个非常不错的原生界面效果组件,我们可以通过利用其各种界面控件,结合Python跨平台运行的特性,为Windows、MacOS、Ubuntu等Linux系统,开发一套界面效果一致的应用系统。

我们可以基于VSCode+wxpython+wxFormBuilder组合实现桌面端的开发,可以利用wxFormBuilder来快速生成一些界面效果进行重用,wxFormBuilder类似WinForms里面的窗体设计器,完成设计后生成Python的类代码即可在项目中直接使用。

下面是相关的资源地址:

wxpython:https://www.wxpython.org/

wxFormBuilder: https://github.com/wxFormBuilder/wxFormBuilder

以及一些Github上的案例项目:

https://github.com/janbodnar/wxPython-examples

wxPython 帮助文档和案例:https://extras.wxpython.org/wxPython4/extras

wxPython基础教程:https://www.w3ccoo.com/wxpython/index.html

在开始介绍WxPython界面组件之前,我们先来了解一下案例的界面效果,然后在逐步深入了解。由于它可以再不同的系统上运行,因此我们分别截图MacOS、Windows系统的界面效果来介绍。

下面是在不同的系统中创建一些主体界面元素作为参考。

MacOS中的界面效果:

Windows系统的界面效果:

两者界面很类似,这里包含了常用的菜单、工具栏、状态栏、多面板和多文档界面等界面元素,作为主体框架界面,剩下的根据不同的业务,构建列表展示界面、编辑/查看记录界面等常规处理即可。

1、wxPython 中主要类的继承关系

为了研究wxpython的各个界面元素,我们需要了解一下它们之间的关系。

以下是 wxPython 中主要类的继承关系和一些重要类的详细列表:

1. wx.Object

  • 基类,所有 wxPython 类的基础。

2. wx.EvtHandler

  • 处理事件的基类。
  • 主要派生类:
    • wx.Window (也作为 wx.Control 的基类)

3. wx.Window

  • 所有窗口类的基类。
  • 主要派生类:
    • wx.Frame: 主框架窗口。
    • wx.Dialog: 对话框窗口。
    • wx.Panel: 面板,容纳其他控件。
    • wx.MDIParentFrame: MDI(多文档界面)父窗口。
    • wx.MDIChildFrame: MDI 子窗口。
    • wx.ScrolledWindow: 支持滚动的窗口。

4. wx.Control

  • 控件的基类。
  • 主要派生类:
    • wx.Button: 按钮控件。
    • wx.TextCtrl: 文本输入框。
    • wx.CheckBox: 复选框。
    • wx.RadioButton: 单选框。
    • wx.ListBox: 列表框。
    • wx.ComboBox: 下拉框。
    • wx.Slider: 滑块控件。
    • wx.StaticText: 静态文本显示控件。
    • wx.StaticBitmap: 静态位图显示控件。
    • wx.Choice: 选择框控件。
    • wx.TreeCtrl: 树形控件。
    • wx.ListCtrl: 列表控件

5. wx.Sizer

  • 布局管理类的基类。
  • 主要派生类:
    • wx.BoxSizer: 水平或垂直排列控件。
    • wx.GridSizer: 网格布局。
    • wx.FlexGridSizer: 灵活网格布局。
    • wx.StaticBoxSizer: 包含静态框的布局。
    • wx.WrapSizer: 自动换行的布局管理器。

6. wx.Menu

  • 菜单类。
  • 主要派生类:
    • wx.MenuBar: 菜单栏类。
    • wx.PopupMenu: 弹出菜单类。

7. wx.ToolBar

  • 工具栏类。

8. wx.StatusBar

  • 状态栏类。

9. wx.Notebook

  • 选项卡控件,允许用户在多个页面之间切换。

10. wx.AuToolBar

  • 自定义工具栏类,支持多种风格和特性。

另外还提供了RibbonBar的工具栏效果,如下所示

如果我们使用SplitterWindow,那么可以把界面分拆为几个部分。

这些类提供了 wxPython 的基础功能,使得开发者能够构建复杂的 GUI 应用程序。每个类都有自己的一组方法和属性,可以参考 wxPython 的官方文档来了解具体的使用方式和示例。

2、案例的界面代码分析

了解了案例界面后,我们可以看看他们的界面代码是如何处理的。

class AUIDemoApp(wx.Frame):
"""带AUI管理的多文档主窗口""" id_open = wx.NewIdRef()
id_save = wx.NewIdRef()
id_quit = wx.NewIdRef() id_help = wx.NewIdRef()
id_about = wx.NewIdRef() def __init__(self, parent):
# super(AUIDemoApp, self).__init__(None, title="AUI 多文档界面", size=(1000, 700)) wx.Frame.__init__(self, parent, style=wx.DEFAULT_FRAME_STYLE)
self.SetTitle("AUI 多文档界面,包含菜单、工具栏、状态栏")
self.SetIcon(appIcon.Icon)
self.SetBackgroundColour((224, 224, 224)) # 设置窗口背景色
self.SetSize((1000, 700))
wx.Image.SetDefaultLoadFlags(0) # 解决图片加载问题 self._init_ui()
self.Center()

这个部分是主界面窗口的初始化函数,其中设置标题、图标、背景色、以及尺寸等,并通过 _init_ui()函数来实现所有界面元素的初始化,如工具栏、菜单栏、状态栏,以及多文档界面的布局。

初始化界面的代码主要内容如下所示。

这里使用 aui.AuiManager 来控制多个可以停靠面板的显示处理。菜单栏的初始化的代码,如下所示。

    def _create_menubar(self):
"""创建菜单栏""" self.mb = wx.MenuBar() # 文件菜单
m = wx.Menu()
m.Append(self.id_open, "打开文件")
m.Append(self.id_save, "保存文件")
m.AppendSeparator()
m.Append(self.id_quit, "退出系统")
self.mb.Append(m, "文件") # self.Bind(wx.EVT_MENU, self.on_open, id=self.id_open)
# self.Bind(wx.EVT_MENU, self.on_save, id=self.id_save)
# self.Bind(wx.EVT_MENU, self.on_quit, id=self.id_quit) # 帮助菜单
m = wx.Menu()
m.Append(self.id_help, "帮助主题")
m.Append(self.id_about, "关于...")
self.mb.Append(m, "帮助") # self.Bind(wx.EVT_MENU, self.on_help, id=self.id_help)
# self.Bind(wx.EVT_MENU, self.on_about, id=self.id_about) self.SetMenuBar(self.mb)

状态栏的代码处理如下所示。

    def createStatusBar(self):
# 创建自定义状态栏
self.status_bar = wx.StatusBar(self)
self.SetStatusBar(self.status_bar)
self.status_bar.SetFieldsCount(3) # 设置字段数量
self.status_bar.SetStatusText("Ready", 0) # 第一个字段
self.status_bar.SetStatusText("No document opened", 1) # 第二个字段 # 获取今天的日历
calendar_today = getCalendar_today()
self.status_bar.SetStatusText(calendar_today, 2) # 第三个字段

工具栏界面代码初始化如下所示。

    def _create_toolbar(self, d="H"):
"""创建工具栏"""
# 工具栏图标,使用嵌入的图片
# bmp_open = wx.Bitmap("wxpython/images/32/calc.png", wx.BITMAP_TYPE_PNG)
bmp_open = book.Bitmap
bmp_save = clock.Bitmap
bmp_help = email.Bitmap
bmp_about = home.Bitmap if d.upper() in ["V", "VERTICAL"]:
tb = aui.AuiToolBar(
self,
-1,
wx.DefaultPosition,
wx.DefaultSize,
agwStyle=aui.AUI_TB_TEXT | aui.AUI_TB_VERTICAL,
)
else:
tb = aui.AuiToolBar(
self, -1, wx.DefaultPosition, wx.DefaultSize, agwStyle=aui.AUI_TB_TEXT
)
tb.SetToolBitmapSize(wx.Size(16, 16)) tb.AddSimpleTool(self.id_open, "打开", bmp_open, "打开文件")
tb.AddSimpleTool(self.id_save, "保存", bmp_save, "保存文件")
tb.AddSeparator()
tb.AddSimpleTool(self.id_help, "帮助", bmp_help, "帮助")
tb.AddSimpleTool(self.id_about, "关于", bmp_about, "关于") tb.Realize()
return tb

其中注释的代码: bmp_open = wx.Bitmap("wxpython/images/32/calc.png", wx.BITMAP_TYPE_PNG)

是用来加载图片路径的资源,有时候我们为了减少一些常见图片文件的依赖,我们可以把他们放在统一的地方,使用代码的方式处理

如下代码所示,使用PyEmbeddedImage来直接嵌入图片的Base64代码。

book = PyEmbeddedImage(
b"""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"""
)

主界面中放置了一个多文档的文档对象,使用aui.NoteBook界面对象即可,如下代码所示。

        # 创建AuiNotebook用于多文档管理
self.notebook = aui.AuiNotebook(
self, style=aui.AUI_NB_CLOSE_ON_ALL_TABS | aui.AUI_NB_TAB_SPLIT
)
self.mgr.AddPane(self.notebook, aui.AuiPaneInfo().CenterPane())

如果我们想初始化一个窗体界面在AuiNoteBook组件中,那么如下所示。

        # 创建初始文档面板
self.document_panel = DocumentPanel(self)
icon = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))
self.notebook.AddPage(self.document_panel, "Document", select=True, bitmap=icon)

当然,我们可以进一步优化上面的实例代码,使得工具栏、菜单栏的内容动态根据配置生成界面,这样就可以避免手工添加的麻烦。

后续会继续根据我Winform开发框架的一些界面设计效果,进一步完善基于Wxpython组件界面的处理,构建一个基于Python后端Web API或者本地多种数据库操作的通用应用系统的管理,包括用户、角色、机构、权限、日志、菜单、字典、附件等基础框架内容的处理效果。

基于wxpython的跨平台桌面应用系统开发的更多相关文章

  1. 基于SSH框架的网上书店系统开发的质量属性

    基于SSH框架的网上书店系统开发的质量属性 对于我的基于SSH框架的网上书店系统的开发要实现的质量属性有可用性.可修改性.性能.安全性.易用性和可测试性. 1.对于可用性方面的战术: 可用性(Avai ...

  2. 快速了解Electron:新一代基于Web的跨平台桌面技术

    本文引用了作者“ ConardLi”的<用JS开发跨平台桌面应用,从原理到实践>一文部分内容,原文链接:segmentfault.com/a/1190000019426512,感谢原作者的 ...

  3. 基于ssh框架的在线考试系统开发的质量属性

    我做的系统是基于ssh框架的在线考试系统.在线考试系统有以下几点特性:(1)系统响应时间需要非常快,可以迅速的出题,答题.(2)系统的负载量也需要非常大,可以支持多人在线考试(3)还有系统的安全性也需 ...

  4. 基于SSH框架的在线考勤系统开发的质量属性

    我要开发的是一个基于SSH框架的在线考勤系统. 质量属性是指影响质量的相关因素,下面我将分别从6个系统质量属性(可用性,易用性,可修改性,性能,安全性,可测试性)来分析我的系统,以及如何实现这些质量属 ...

  5. 基于类和redis的监控系统开发

    最近学习python运维开发,编写得一个简单的监控系统,现记录如下,仅供学习参考. 整个程序分为7个部分: 第一个部分根据监控架构设计文档架构如下: .├── m_client│   ├── conf ...

  6. 【转贴】-- 基于QT的跨平台应用开发

    原帖地址:http://www.cnblogs.com/R0b1n/p/4106613.html 1 Qt简介 Qt是1991年奇趣科技开发的一个跨平台的C++图形用户界面应用程序框架.它提供给应用程 ...

  7. Electron+Vue开发跨平台桌面应用

    Electron+Vue开发跨平台桌面应用 xiangzhihong发布于 2019-12-23 虽然B/S是目前开发的主流,但是C/S仍然有很大的市场需求.受限于浏览器的沙盒限制,网页应用无法满足某 ...

  8. 基于C/S架构的3D对战网络游戏C++框架 _05搭建系统开发环境与Boost智能指针、内存池初步了解

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  9. 基于Jenkins自动构建系统开发

    1  绪论 1.1 课题的研究背景 随着IT行业的不断发展,软件开发的复杂度也随着不断提高.与此同时,软件的开发团队也越来越庞大,而如何更好地协同整个团队进行高效准确的工作,从而确保软件开发的质量已经 ...

  10. 使用nodegui 开发高性能的跨平台桌面端应用

    nodegui 是基于qt + nodejs 的跨平台桌面开发方案,官方同时也提供了很不错的文档 简单使用 使用官方的starter clone 代码 git clone https://github ...

随机推荐

  1. 15-canvas渐变色

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...

  2. dubbo超时异常 荐

    dubbo超时异常 在调用dubbo服务时经常看到如下错误: Caused by: com.alibaba.dubbo.remoting.TimeoutException: Waiting serve ...

  3. 7. 从0学ARM-GNU伪指令、代码编译,lds使用

    <嵌入式工程师到底要不要学习ARM汇编指令?arm学习文章汇总> <到底什么是Cortex.ARMv8.arm架构.ARM指令集.soc?一文帮你梳理基础概念[科普]> 关于A ...

  4. APT 使用

    使用 Ubuntu 包搜索器 apt 命令 功能 apt install 安装软件包 apt remove 移除软件包 apt purge 移除软件包及配置文件 apt update 刷新存储库索引 ...

  5. [postgres]使用pgbench进行基准测试

    前言 pgbench是一种在postgres上进行基准测试的简单程序,一般安装后就会自带.pgbench可以再并发的数据库绘画中一遍遍地进行相同序列的SQL语句,并且计算平均事务率. 测试准备 既然要 ...

  6. iptables 工作过程整理

    转载注明出处: 1.概念和工作原理 iptables是Linux系统中用来配置防火墙的命令.iptables是工作在TCP/IP的二.三.四层,当主机收到一个数据包后,数据包先在内核空间处理,若发现目 ...

  7. C++ weak_ptr除了解决循环引用还能做什么?

    C++: weak_ptr到底有什么用? 很多人对std::weak_ptr的认识只是不增加std::shared_ptr的引用计数,可以用来解决std::shared_ptr可能造成的循环引用问题. ...

  8. Go runtime 调度器精讲(五):调度策略

    原创文章,欢迎转载,转载请注明出处,谢谢. 0. 前言 在 第四讲 我们介绍了 main goroutine 是如何运行的.其中针对 main goroutine 介绍了调度函数 schedule 是 ...

  9. 记一次 RabbitMQ 消费者莫名消失问题的排查

    开心一刻 今天好哥们找我借钱哥们:兄弟,我最近手头紧,能不能借我点...我:我手头也不宽裕,要不你试试银行贷款或者花呗?哥们:不行,那个借了要还的我:... 问题回顾 某天下午,生产监控告警:消息积压 ...

  10. I found that CTH has no RP when i tried to reduce his RP