痞子衡嵌入式:极易上手的可视化wxPython GUI构建工具(wxFormBuilder)
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是wxPython GUI构建工具wxFormBuilder。
一、手工代码布局GUI界面的烦恼
如果你曾经设计过上位机软件GUI界面,初始阶段一定是纯手工代码布局GUI界面上的各个控件,相信你肯定遇到过如下烦恼:
- 控件类型较难找:UI界面里有很多控件类型,纯手工写代码需要翻看文档一个个去查找这些控件的名字与用法。
- 尺寸位置难调整:如果界面上已经布了多个控件,想要整体去调整这些控件的尺寸与位置是一件头疼的事。
- 效果查看不实时:每新添加一个控件都需要运行才能查看整体效果,如果代码添加不完善,可能无法运行看不到效果。
二、wxFormBuilder工具背景
在讲本文主角wxFormBuilder之前有必要提一下这个软件的来历,首先要追述到大名鼎鼎的跨平台GUI库wxWidgets,这个库主要是用C++语言实现的;鉴于wxWidgets的流行,Robin Dunn用Python语言对wxWidgets做了一层封装,封装后便成了Python版GUI库wxPython;下面是这两个GUI库的官方主页:
- wxWidgets项目官方主页: https://www.wxwidgets.org/
- wxPython项目官方主页: https://www.wxpython.org/
wxWidgets的各种UI控件功能均是通过class来实现的,这个链接 http://docs.wxwidgets.org/3.0/page_class_cat.html 列出了wxWidgets里的所有class,wxPython并没有实现wxWidgets里全部class,但基本实现了大部分常用class,这个链接 https://docs.wxpython.org/wx.1moduleindex.html 列出了wxPython里所有的class。
知道了wxPython的class便可以开始设计GUI界面,但手工写代码设计界面太繁琐,因此wxFormBuilder应运而生,这是一款能够可视化设计界面的工具(并不是唯一工具,还有wxGlade、Boa Constructor等),通过该工具设计GUI界面后可自动生成wxPython代码,下面是wxFormBuilder的官方主页:
- wxFormBuilder项目Github: https://github.com/wxFormBuilder/wxFormBuilder
三、wxFormBuilder快速上手
使用wxFormBuilder去设计GUI界面可以不用掌握wxPython里的各个控件class的具体用法,你只需要在wxFormBuilder软件里添加这些控件即可,下面痞子衡将简介wxFormBuilder的用法:
3.1软件界面
安装好wxFormBuilder软件之后打开这个软件,可见到如下界面,界面主要分为四大区:项目区、控件区、编辑区、属性区。软件使用起来非常简单,就是在【控件区】里点击添加需要的控件,这些控件的效果会在【编辑区】里实时显示,并在【属性区】这些控件的属性,【项目区】用于显示控件间的层级关系。
3.2基础布局
让我们开始创建一个GUI的基础框架,基础框架包括:Frame(外围轮廓)、Sizer(内部控件区)、menubar(顶部菜单栏)、statusBar(底部状态栏)。
第一步是添加一个Frame,这是GUI的轮廓基础,其size(default为500; 300)决定了GUI整体界面的大小。
第二步是在Frame下添加一个Sizer,后续所有控件均是放在Sizer里的。关于Sizer部分需要特别说明一下,wxPython提供的Sizer类型有如下七种:wxBoxSizer、wxWrapSizer、wxStaticBoxSizer、wxGridSizer、wxFlexGridSizer、wxGridBagSizer、wxStdDialogButtonSizer,Sizer的样式决定了后续控件的整体相对位置关系,选定了Sizer即选定了GUI界面样式。关于这七种Sizer的具体样式请见 https://docs.wxpython.org/sizers_overview.html#sizers-overview。如果你觉得单个Sizer里的控件布局太单调,你可以嵌套使用Sizer,这是实现GUI界面控件布局多样化的关键。
第三步是在Frame顶部添加一个menubar:
第四步是在Frame底部添加一个statusBar:
3.3多种控件
基础布局搞定之后,接下来便是在Sizer里添加控件,wxPython支持的控件非常丰富,其中比较常用的是如下几个:button(按钮)、staticText(静态显示文本框)、textCtrl(输入输出文本框)、Choice(复选框)、checkBox(选中框)、slider(滑动条)。前面痞子衡选择的Sizer是wxBoxSizer,即自上而下布局,因此这些控件在Sizer是自上而下排列的,各个控件的位置后续在属性里还可以微调,但改变不了自上而下的格局。
3.4控件属性
添加了所有控件之后,下一步便是分别设置控件的属性,进一步调整控件。痞子衡以Button属性为例,痞子衡勾选了如下4项比较重要的属性设置,分别是name(button在后续python代码的对象名,一般需要按其功能修改,修改后使得代码阅读/修改起来更直观)、label(button在GUI里显示的标签名,此处是MyButton,也需要按其功能修改,方便用户使用软件)、size(设置button的尺寸,这个尺寸最大不应超过Sizer尺寸)、flag(调整对齐方式从而调整Button在Sizer里的位置)。另外有一个属性不得不说,即控件位置pos,在wxFormBuilder里设置这个属性并不生效,痞子衡猜想可能跟Sizer样式有关,因为Sizer决定了控件间相对位置关系,因此控件的pos不能随意设置。
3.5触发事件
有些控件是需要有响应的,比如Button,在GUI软件实际使用中,用户如果按下了Button,应该需要触发某个任务,任务需要有响应函数,这个响应函数需要在【Events】里设置,Button的响应函数在OnButtonClick里设置,痞子衡在这里指定了响应函数名为showMessage。在wxFormBuilder里我们只需要指定控件响应函数名即可,响应函数的具体功能实现,不属于wxFormBuilder设计范畴。
3.6生成代码
当GUI界面布局全部完成之后,需选择File->Generate Code或F8生成python代码,需要复制所有的python代码并保存在单独的文件里,痞子衡保存在了my_win.py文件里。
可以简单看一下这个my_win.py里的内容,代码里首先import了wx库(即wxPython库),并定义了名为MyFrame1的class,这个class主要包含两个函数__init__()和showMessage():__init__()里初始化了各个控件成员self.m_xx,这与我们在wxFormBuilder里添加控件是对应的;showMessage()是Button控件的响应函数,但这个响应函数并没有任何实质代码,当然我们可以在这个函数里面实现Button响应功能,但一般不建议直接在wxFormBuilder生成的代码里添加代码,因为你可能随时调整GUI页面布局,那么main_win.py里的代码会重新生成,这样会覆盖我们自己添加的代码,导致维护起来比较麻烦。
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Jul 11 2018)
## http://www.wxformbuilder.org/
##
## PLEASE DO *NOT* EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
###########################################################################
## Class MyFrame1
###########################################################################
class MyFrame1 ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
bSizer1 = wx.BoxSizer( wx.VERTICAL )
self.m_button1 = wx.Button( self, wx.ID_ANY, u"MyButton", wx.Point( -1,-1 ), wx.DefaultSize, 0 )
bSizer1.Add( self.m_button1, 0, wx.ALL, 5 )
self.m_staticText1 = wx.StaticText( self, wx.ID_ANY, u"MyLabel", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText1.Wrap( -1 )
bSizer1.Add( self.m_staticText1, 0, wx.ALL, 5 )
self.m_textCtrl1 = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.Point( -1,-1 ), wx.DefaultSize, 0 )
bSizer1.Add( self.m_textCtrl1, 0, wx.ALL, 5 )
m_choice1Choices = []
self.m_choice1 = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice1Choices, 0 )
self.m_choice1.SetSelection( 0 )
bSizer1.Add( self.m_choice1, 0, wx.ALL, 5 )
self.m_checkBox1 = wx.CheckBox( self, wx.ID_ANY, u"Check Me!", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer1.Add( self.m_checkBox1, 0, wx.ALL, 5 )
self.m_slider1 = wx.Slider( self, wx.ID_ANY, 50, 0, 100, wx.DefaultPosition, wx.DefaultSize, wx.SL_HORIZONTAL )
bSizer1.Add( self.m_slider1, 0, wx.ALL, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.m_menubar1 = wx.MenuBar( 0 )
self.m_menu1 = wx.Menu()
self.m_menuItem1 = wx.MenuItem( self.m_menu1, wx.ID_ANY, u"MyMenuItem", wx.EmptyString, wx.ITEM_NORMAL )
self.m_menu1.Append( self.m_menuItem1 )
self.m_menubar1.Append( self.m_menu1, u"MyMenu" )
self.SetMenuBar( self.m_menubar1 )
self.m_statusBar1 = self.CreateStatusBar( 1, wx.STB_SIZEGRIP, wx.ID_ANY )
self.Centre( wx.BOTH )
# Connect Events
self.m_button1.Bind( wx.EVT_BUTTON, self.showMessage )
def __del__( self ):
pass
# Virtual event handlers, overide them in your derived class
def showMessage( self, event ):
event.Skip()
四、使用wxFormBuilder生成的代码
前面已经使用wxFormBuilder生成GUI界面类MyFrame1并保存在my_win.py文件中,此时需要创建一个主函数文件去调用MyFrame1,下面是痞子衡创建的main_win.py中的代码:
import wx
# 导入my_win.py中内容
import my_win
# 创建mainWin类并传入my_win.MyFrame1
class mainWin(my_win.MyFrame1):
# 实现Button控件的响应函数showMessage
def showMessage(self, event):
self.m_textCtrl1.Clear()
self.m_textCtrl1.SetValue('hello world')
if __name__ == '__main__':
# 下面是使用wxPython的固定用法
app = wx.App()
main_win = mainWin(None)
main_win.Show()
app.MainLoop()
最后让我们测试一下这个GUI软件,在命令行下运行main_win.py
PS D:\my_git_repo\> python .\main_win.py
至此,wxPython GUI构建工具wxFormBuilder痞子衡便介绍完毕了,掌声在哪里~~~
参考资料
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。
痞子衡嵌入式:极易上手的可视化wxPython GUI构建工具(wxFormBuilder)的更多相关文章
- 痞子衡嵌入式:超级好用的可视化PyQt GUI构建工具(Qt Designer)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是PyQt GUI构建工具Qt Designer. 痞子衡开博客至今已有好几年,一直以嵌入式开发相关主题的文章为主线,偶尔穿插一些其他技术 ...
- 痞子衡嵌入式:备受开源社区推崇的分布式版本控制工具(Git)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是分布式版本控制工具Git. 1.为什么需要版本控制系统? 单人软件项目开发过程,往往很多功能都是逐步增加的,在代码开发过程中,有的时候功 ...
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记 - 索引
大家好,我是痞子衡,是正经搞技术的痞子.本系列痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生. 串口调试助手是嵌入式开发里非常常用的小工具,市面上有非常多流行的串口调试工具,比如TeraTe ...
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(2)- 界面构建(wxFormBuilder3.8.0)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之界面构建. 一个软件的UI界面是非常重要的,这是软件与用户交互的接口,软件功能即使再强大,但如果没 ...
- 痞子衡嵌入式:恩智浦MCU安全加密启动一站式工具NXP-MCUBootUtility用户指南
NXP MCU Boot Utility English | 中文 1 软件概览 1.1 介绍 NXP-MCUBootUtility是一个专为NXP MCU安全加密启动而设计的工具,其特性与NXP M ...
- 痞子衡嵌入式:语音处理工具Jays-PySPEECH诞生记(3)- 音频显示实现(Matplotlib, NumPy1.15.0)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是语音处理工具Jays-PySPEECH诞生之音频显示实现. 音频显示是Jays-PySPEECH的主要功能,Jays-PySPEECH借 ...
- 痞子衡嵌入式:知名半导体MCU大厂软件开发C代码规范
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是飞思卡尔软件开发C语言编码规范. 2020鼠年春节是个漫长的假期,痞子衡在家百无聊赖,翻出了2016年10月1日(这个时间是痞子衡正式开始 ...
- 痞子衡嵌入式:盘点国内Cortex-M内核MCU厂商高性能产品
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是国内Cortex-M内核MCU厂商高性能产品. 在8/16位中低端MCU领域,国内厂商的本土化产品设计以及超低价特点,使得其与国外大厂竞 ...
- 痞子衡嵌入式:飞思卡尔i.MX RT系列MCU启动那些事(8)- 从Raw NAND启动
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RT系列MCU的Raw NAND启动. 前面铺垫了七篇启动系列文章,终于该讲具体Boot Device了,我们知道i. ...
随机推荐
- Spring IOC(三)依赖注入
本系列目录: Spring IOC(一)概览 Spring IOC(二)容器初始化 Spring IOC(三)依赖注入 Spring IOC(四)总结 目录 1.AbstractBeanFactory ...
- Ubuntu 18 安装chrome
1.下载chrome文件 32位使用如下命令 wget https://dl.google.com/linux/direct/google-chrome-stable_current_i386.deb ...
- 入门级 JAVA反射机制
1.什么是反射? Java中的反射机制是Java语言的一个很重要的特性,是Java “动态性” 的重要体现.Java反射机制让我们在程序运行状态中,对于任意一个类,都能知道这个类的所有属性和方法:对于 ...
- jdk源码阅读笔记-String
本人自学java两年,有幸初入这个行业,所以功力尚浅,本着学习与交流的态度写一些学习随笔,什么错误的地方,热烈地希望园友们提出来,我们共同进步!这是我入园写的第一篇文章,写得可能会很乱. 一.什么是S ...
- Boosting(提升方法)之XGBoost
XGBoost是一个机器学习味道非常浓厚的模型,在数学上非常规范,运用正则化.L2范数.二阶梯度.泰勒公式和分布式计算方法,对GBDT等提升树模型进行优化,不仅能处理更大规模的数据,而且运行效率特别高 ...
- 网络协议 22 - RPC 协议(下)- 二进制类 RPC 协议
前面我们认识了两个常用文本类的 RPC 协议,对于陌生人之间的沟通,用 NBA.CBA 这样的缩略语,会使得协议约定非常不方便. 在讲 CDN 和 DNS 的时候,我们讲过接入层的设计 ...
- 基于百度AI开放平台的人脸识别及语音合成
基于百度AI的人脸识别及语音合成课题 课题需求 (1)人脸识别 在Web界面上传人的照片,后台使用Java技术接收图片,然后对图片进行解码,调用云平台接口识别人脸特征,接收平台返回的人员年龄.性别.颜 ...
- 新手学习WEB前端流程以及学习中常见的误区
学习web前端编程技术肯定是以就业拿到高薪工作为主要目的的,可是高薪不会那么轻易拿到,这是一个最简单的道理.没有付出就没有回报,在整个学习web前端编程技术的过程中,你需要付出时间.精力.金钱.废话不 ...
- DOM-based XSS Test Cases
Case 23 - DOM Injection via URL parameter (by server + client) https://brutelogic.com.br/dom/dom.php ...
- 5.App Inventor 2编程实例--指南针
本视频来自:https://www.17coding.net 的 国庆特辑——指南针 共3个视频. 注意: 项目名字要使用英文. 项目完成后可以选择“打包APK”—“ 打包APK并下载到电脑”,然后 ...