目录
wxPython领域介绍
wxPython是用Python写的跨平台GUI工具,通俗的理解就是用来写软件界面的包。与之功能类似的Python包有 PyQt、Tkinter、PyGtk等等,其中PyQt内容丰富,功能强大,网上资源也很多,但是上手难度较大。我选择的wxpython上手相对简单,但是网上资源较少,实现相关功能时需要在参考官方文档。
关于这篇笔记不会从hello world 开始介绍wxpyhton,我会直接介绍我学习完后的一些经验,由于我涉及的功能并没有完全发挥出wxpython的强大功能,在这里给一些学习方案,新手大神均可食用
入门:推荐看书 《Wxpython in Action》《Creating GUI Applications with wxPython》
提高:官方案例库:https://extras.wxpython.org/wxPython4/extras/4.0.0/
进阶:官网:https://wxpython.org/pages/downloads/
安装 wxpython
pip install wxPython
wxpyhton 基础知识
了解界面构成
常见的GUI界面包含五个部分:主界面(main window), 菜单页面(menu), 按键(button), 标签(labels), 文本输入(text entry),如下图所示,图中多了一个画布。
在wxpython中,为了更好的实现GUI编写,封装了多个类,常用的除了有wx.Frame(对应主界面)、wx.MenuBar()(对应菜单类)、wx.Button(对应按键)、wx.StaticText(对应label)、wx.TextCtrl(对应text entry)、wx.lib.plot.PlotCanvas(对应画布)与上图对应之外,还有wx.Panel,可以按照下图的方式理解,也就是一个Frame可以包含多个Panel,Panel里面可以包含label、text、plot,但是一个Frame只能有一个Menu!!
另外还有一个重要的类为wx.Dialog
,如下图所示,Dialog可以包含多个Panel,常用来实现选项界面,在这里我用来实现串口设置界面。
根据上述的结构,实现的伪代码如下所示
class Dialog(Wx.Dialog):
"""
实现串口设置
"""
class Plane1(wx.Panel):
"""
包含3个按钮、以及label(文字log)和text
"""
class Planel3(wx.Panel):
"""
包含多个label 和 text
"""
calss MainFrame(wx.Frame):
"""
主界面
"""
self.mainmenu = wx.MenuBar() # 注册菜单界面
self.panel_setting = Planel1(self, size=(700,100)) # 注册Panel 1
self.panel_data_pre = wxplot.PlotCanvas(self, size=(700,300)) #注册Panel2→画布1
self.panel_control = Planel3(self, size=(700,100)) # 注册Panel 3
self.panel_data_pro = wxplot.PlotCanvas(self, size=(700,300)) # 注册Panel4→画布2
if __name__ == '__main__':
app = wx.App()
frame = MainFrame(ser) # 将主界面注册到 App中
frame.Show()
app.SetTopWindow(frame)
app.MainLoop() # 运行App
界面布局
了解完界面构成后,下一步需要实现界面布局。界面布局用到的类为wx.BoxSizer
和wx.FlexGridSizer
wx.BoxSizer
表示初始化一个可以设置大小区域,该类的参数orient
默认参数为 HORIZONTAL,也就是水平分布,简单示例如下所示
import wx
class DemoPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
button1 = wx.Button(self, label='1') # 生成按键1,
button2 = wx.Button(self, label='2')
boxsier = wx.BoxSizer(wx.HORIZONTAL) # 生成可设置大小的BoxSizer,并且初始方案为水平分布
boxsier.Add(button1) # 注册 按键1
boxsier.Add(button2)
self.SetSizer(boxsier)
class MainFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='Demo.exe')
demopanel = DemoPanel(self)
self.Show()
if __name__ == '__main__':
app = wx.App()
frame = MainFrame()
app.SetTopWindow(frame)
app.MainLoop()
运行结果展示
更多参数了解参考:https://docs.wxpython.org/wx.BoxSizer.html?highlight=boxsizer#wx.BoxSizer
wx.FlexGridSizer为一个经常使用的将多个部件 规则布局的类,使用如下所示。 其中row和cols表示行和列的个数,vgap和hgap分别表示垂直和水平间距
import wx
class DemoPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
button1 = wx.Button(self, label='1')
button2 = wx.Button(self, label='2')
button3 = wx.Button(self, label='3')
button4 = wx.Button(self, label='4')
button5 = wx.Button(self, label='5')
button6 = wx.Button(self, label='6')
button7 = wx.Button(self, label='7')
button8 = wx.Button(self, label='8')
boxsier = wx.BoxSizer(wx.VERTICAL)
flex = wx.FlexGridSizer(rows=2, cols=4, vgap=5, hgap=5) # 生成2行4列的结构vgap和hgap分别表示垂直和水平间距
flex.Add(button1)
flex.Add(button2)
flex.Add(button3)
flex.Add(button4)
flex.Add(button5)
flex.Add(button6)
flex.Add(button7)
flex.Add(button8)
boxsier.Add(flex)
self.SetSizer(boxsier)
class MainFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='小牛课堂.exe-->v1.0')
demopanel = DemoPanel(self)
self.Show()
if __name__ == '__main__':
app = wx.App()
frame = MainFrame()
app.SetTopWindow(frame)
app.MainLoop()
运行效果
关于wx.FlexGridSizer更多细节了解参考https://docs.wxpython.org/wx.FlexGridSizer.html?highlight=flexgridsizer#wx.FlexGridSizer
在注册按键中使用了函数 Add,其函数参数有``Add(window, proportion=0, flag=0, border=0, userData=None*)。在使用中,flag=wx.CENTER`表示将该组件居中,常用的位置flag有参数有
wx.TOP # 表示与主sizer 哪条边有border的距离
wx.BOTTOM
wx.LEFT
wx.RIGHT
wx.ALL
wx.EXPAND # 扩展到整个可使用的sizer
wx.ALIGN_CENTER or wx.ALIGN_CENTRE
wx.ALIGN_LEFT
wx.ALIGN_RIGHT
wx.ALIGN_RIGHT
wx.ALIGN_TOP
wx.ALIGN_BOTTOM #对齐方式
需要注意的是border参数与flag一起配合使用,如Add(self, 1, wx.CENTER|wx.LEFT, 5)表示该组件与中间对齐并且距离左边界5个像素单位。具体使用参考https://docs.wxpython.org/sizers_overview.html?highlight=add#Add
事件绑定
事件绑定也就是将组件和事件联系起来,比如实现按键关闭窗口,就是通过将按键❌与关闭窗口函数绑定进行实现的。wxpython
的事件绑定函数为Bind
,其使用方法如下所示
import wx
ID_BUTTON = wx.NewId()
class DemoPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
button1 = wx.Button(self, label='1', id=ID_BUTTON)
button1.Bind(wx.EVT_BUTTON, self.button1_handler)
boxsizer = wx.BoxSizer(wx.VERTICAL)
flex = wx.FlexGridSizer(rows=1, cols=1, vgap=5, hgap=5) # 生成2行4列的结构vgap和hgap分别表示垂直和水平间距
flex.Add(button1)
boxsizer.Add(flex)
self.SetSizer(boxsizer)
def button1_handler(self, event):
print("Hello word!")
class MainFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='小牛课堂.exe-->v1.0')
demopanel = DemoPanel(self)
self.Show()
if __name__ == '__main__':
app = wx.App()
frame = MainFrame()
app.SetTopWindow(frame)
app.MainLoop()