Python6-wxPython库
1.wxPython库
官方文档健全:https://docs.wxpython.org/
安装:
pip install wxPython
2.窗口程序
2.1 简单的窗口程序
import wx
# 创建应用程序对象
app = wx.App()
# 创建窗口对象
# parent为None表示这是一个顶级窗口
frm = wx.Frame(None, title="第一个Python程序", size=(400, 300), pos=(100, 100))
# 显示窗口
frm.Show()
# 进入主事件循环
app.MainLoop()
2.2 自定义窗口类
import wx
# 自定义窗口类
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="第一个Python程序", size=(400, 300), pos=(100, 100))
# 你的代码
# 创建应用程序对象
app = wx.App()
# 创建窗口对象
frm = MyFrame()
# 显示窗口
frm.Show()
# 进入主事件循环
app.MainLoop()
2.3 面板与静态文本
面板是一个没有标题栏的容器(可以容纳其它控件的控件)。
import wx
#自定义窗口类
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None,title = "第一个Python程序",size = (400,300),pos = (100,100))
# 设置面板所在的父容器是当前窗口
panel = wx.Panel(parent = self)
# 将静态文本放到面板中
staticext = wx.StaticText(parent = panel, label = "Hello World!", pos = (10,10))
app = wx.App() #创建应用程序对象
frm = MyFrame() #创建窗口对象
frm.Show() #显示窗口
app.MainLoop() #进入主事件循环
2.4 事件处理
1.事件源:事件发生的场所,就是各个控件。
2.事件:wxPython中的事件被封装为事件类wx.Event
及其子类,例如按钮事件类是wx.CommandEvent
,鼠标事件类是wx.MoveEvent
。
3.事件处理程序:一个响应用户事件的方法。
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="事件处理", size=(300, 180))
panel = wx.Panel(parent=self)
self.statictext = wx.StaticText(parent=panel, label="请单击点击按钮", pos=(110, 20))
b = wx.Button(parent=panel, label="OK", pos=(100, 50))
# 绑定wx.EVT_BUTTON按钮单击事件,按钮b是事件源
self.Bind(wx.EVT_BUTTON, self.on_click, b)
def on_click(self, event):
self.statictext.SetLabelText("Hello,World.")
app = wx.App() # 创建应用程序对象
frm = MyFrame() # 创建窗口对象
frm.Show() # 显示窗口
app.MainLoop() # 进入主事件循环
3.布局管理器
3.1 盒子布局管理
wxPython提供了布局管理器类帮助实现界面布局, 主要分为两大类: 盒子布局管理器和网格布局管理器。 盒子布局类似于CSS中的弹性布局, 非常灵活, 我们重点介绍盒子布局。
盒子布局管理器类是wx.BoxSizer, Box布局管理器是最常用的布局管理器, 它可以让其中的子窗口(或控件) 沿垂直或水平方向布局。
1.创建盒子布局管理器对象我们使用wx.BoxSizer类创建盒子布局管理器对象, 主要的构造方法如下:
# 设置水平方向布局(默认)
wx.BoxSizer(wx.HORIZONTAL)
# 设置垂直方向布局
wx.BoxSizer(wx.VERTICAL)
2 添加子窗口(或控件) 到父窗口我们使用wx.BoxSizer对象的Add() 方法添加子窗口(或控件) 到父窗口, 对Add() 方法的语法说明如下:
proportion参数用于设置当前子窗口(或控件) 在父窗口中所占的空间比例; flag参数是布局标志, 用来控制对齐方式、 边框和调整尺寸; border参数用于设置边框的宽度。
# 添加到父窗口中
Add(window, proportion=0, flag=0, border=0)
# 添加到另一个布局对象,用于布局嵌套
Add(sizer, proportion=0, flag=0, border=0)
# 下面是几个flag对齐标志
wx.ALIGN_TOP # 顶对齐
wx.ALIGN_BOTTOM # 底对齐
wx.ALIGN_LEFT # 左对齐
wx.ALIGN_RIGHT # 右对齐
wx.ALIGN_CENTER # 居中对齐
# 下面是flag边框标志
wx.TOP # 设置有顶部边框,边框的宽度需要通过Add()方法的border参数设置
wx.BOTTOM # 设置有底部边框
wx.LEFT # 设置有左边框
wx.RIGHT # 设置有右边框
wx.ALL # 设置4面全有边框
# flag调整尺寸标志
wx.EXPAND # 调整子窗口(或控件)完全填满有效空间
wx.SHAPED # 调整子窗口(或控件)填充有效空间,担保存宽高比
wx.FIXED_MINSIZE # # 调整子窗口(或控件)为最小尺寸
wx.RESERVE_SPACE_EVENT_IF_HIDDEN # 子窗口(或控件)如果被隐藏,则所占空间保留
示例:
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="事件处理", size=(300, 180))
panel = wx.Panel(parent=self)
self.statictext = wx.StaticText(parent=panel, label="请单击OK按钮")
b = wx.Button(parent=panel, label="OK")
self.Bind(wx.EVT_BUTTON, self.on_click, b)
# 创建垂直方向的盒子布局管理器对象vbox
vbox = wx.BoxSizer(wx.VERTICAL)
# 添加静态文本到vbox布局管理器
vbox.Add(self.statictext, proportion=1,
flag=wx.ALIGN_CENTER_HORIZONTAL | wx.FIXED_MINSIZE | wx.TOP, border=30)
# 添加按钮b到vbox布局管理器
vbox.Add(b, proportion=1, flag=wx.EXPAND | wx.BOTTOM, border=10)
# 设置面板(panel)采用vbox布局管理器
panel.SetSizer(vbox)
def on_click(self, event):
self.statictext.SetLabelText("Hello,World.")
app = wx.App() # 创建应用程序对象
frm = MyFrame() # 创建窗口对象
frm.Show() # 显示窗口
app.MainLoop() # 进入主事件循环
盒子布局管理器的嵌套:
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="布局管理器嵌套", size=(300, 120))
panel = wx.Panel(parent=self)
self.statictext = wx.StaticText(parent=panel, label="请单击按钮")
b1 = wx.Button(parent=panel, id=10, label="Button1")
b2 = wx.Button(parent=panel, id=11, label="Button2")
# 创建水平方向的盒子布局管理器hbox对象
hbox = wx.BoxSizer(wx.HORIZONTAL)
# 添加b1到hbox布局管理
hbox.Add(b1, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
# 添加b1到hbox布局管理
hbox.Add(b2, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
# 创建垂直方向的盒子布局管理器vbox
vbox = wx.BoxSizer(wx.VERTICAL)
# 添加静态文本到vbox布局管理器
vbox.Add(self.statictext, proportion=1,
flag=wx.CENTER | wx.FIXED_MINSIZE | wx.TOP, border=10)
# 将水平hbox布局管理器对象到垂直vbox布局管理器对象
vbox.Add(hbox, proportion=1, flag=wx.CENTER)
# 设置面板(pboxanel)采用v布局管理器
panel.SetSizer(vbox)
# 将两按钮(b1和b2)的单击事件绑定到self.on_click方法
self.Bind(wx.EVT_BUTTON, self.on_click, id=10, id2=20)
def on_click(self, event):
event_id = event.GetId()
print(event_id)
if event_id == 10:
self.statictext.SetLabelText("Button1单击")
else:
self.statictext.SetLabelText("Button2单击")
app = wx.App() # 创建应用程序对象
frm = MyFrame() # 创建窗口对象
frm.Show() # 显示窗口
app.MainLoop() # 进入主事件循环
4.控件
4.1 文本输入框
在界面中实现三个文本输入控件和三个静态文本:
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="文件输入控件", size=(300, 260))
panel = wx.Panel(parent=self)
tc1 = wx.TextCtrl(panel)
tc2 = wx.TextCtrl(panel, style=wx.TE_PASSWORD)
tc3 = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
userid = wx.StaticText(panel, label="用户ID:")
pwd = wx.StaticText(panel, label="密码:")
content = wx.StaticText(panel, label="多行文本:")
# 创建垂直方向的盒子布局管理器对象
vbox = wx.BoxSizer(wx.VERTICAL)
# 添加控件到vbox布局管理器
vbox.Add(userid, flag=wx.EXPAND | wx.LEFT, border=10)
vbox.Add(tc1, flag=wx.EXPAND | wx.ALL, border=10)
vbox.Add(pwd, flag=wx.EXPAND | wx.LEFT, border=10)
vbox.Add(tc2, flag=wx.EXPAND | wx.LEFT, border=10)
vbox.Add(content, flag=wx.EXPAND | wx.LEFT, border=10)
vbox.Add(tc3, flag=wx.EXPAND | wx.LEFT, border=10)
# 设置面板(panel)采用vbox布局管理器
panel.SetSizer(vbox)
# 设置tc1初始值
tc1.SetValue("tony")
# 获取tc1值
print("读取用户ID:{0}".format(tc1.GetValue()))
app = wx.App() # 创建应用程序对象
frm = MyFrame() # 创建窗口对象
frm.Show() # 显示窗口
app.MainLoop() # 进入主事件循环
4.2 多选框与单选框
在界面中实现一组复选框和一组单选按钮:
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="复选框和单选框", size=(330, 120))
panel = wx.Panel(parent=self)
st1 = wx.StaticText(panel, label="选择你喜欢的编程语言:")
cb1 = wx.CheckBox(panel, id=1, label="Python")
cb2 = wx.CheckBox(panel, id=2, label="Java")
cb2.SetValue(True)
cb3 = wx.CheckBox(panel, id=3, label="C++")
# 绑定id为1~3的所有控件的事件处理到on_checkbox_click
self.Bind(wx.EVT_CHECKBOX, self.on_checkbox_click, id=1, id2=3)
st2 = wx.StaticText(panel, label="选择性别:")
# style为wx.RB_GROUP,说明是一个组的开始,直到遇到另外设置style为wx.RB_GROUP的wx.RadioButton单选按钮为止都是同一个组
radio1 = wx.RadioButton(panel, id=4, label='男', style=wx.RB_GROUP)
radio2 = wx.RadioButton(panel, id=5, label='女')
self.Bind(wx.EVT_RADIOBUTTON, self.on_checkbox_click, id=4, id2=5)
hbox1 = wx.BoxSizer()
hbox1.Add(st1, flag=wx.LEFT | wx.RIGHT, border=5)
hbox1.Add(cb1)
hbox1.Add(cb2)
hbox1.Add(cb3)
hbox2 = wx.BoxSizer()
hbox2.Add(st2, flag=wx.LEFT | wx.RIGHT, border=5)
hbox2.Add(radio1)
hbox2.Add(radio2)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(hbox1, flag=wx.ALL, border=10)
vbox.Add(hbox2, flag=wx.ALL, border=10)
# 设置面板(panel)采用vbox布局管理器
panel.SetSizer(vbox)
def on_checkbox_click(self, event):
# 从事件对象中取出事件源
cb = event.GetEventObject()
print("选择{0},状态{1}".format(cb.GetLabel(), event.IsChecked()))
def on_radio_click(self, event):
rb = event.GetEventObject()
print("第一组{0}被选中".format(rb.GetLabel()))
app = wx.App() # 创建应用程序对象
frm = MyFrame() # 创建窗口对象
frm.Show() # 显示窗口
app.MainLoop() # 进入主事件循环
4.3 列表控件
对列表控件可以进行单选或多选, 列表控件类是wx.ListBox
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="列表", size=(350, 175))
panel = wx.Panel(parent=self)
st1 = wx.StaticText(panel, label="选择你喜欢的编程语言:")
list1 = ['Python', 'C++', 'Java']
# choices设置列表选项,style为wx.LB_SINGLE表示单选
lb1 = wx.ListBox(panel, choices=list1, style=wx.LB_SINGLE)
# 绑定列表选择事件
self.Bind(wx.EVT_LISTBOX, self.on_listbox1, lb1)
st2 = wx.StaticText(panel, label="选择你喜欢吃的水果:")
list2 = ['苹果', '橘子', '香蕉']
# style为wx.LB_EXTENDED表示多选列表控件
# wx.LB_MULTIPLE: 多选。
# wx.LB_EXTENDED: 多选, 但是需要在按住Ctrl或Shift键时选择项目。
# wx.LB_SORT: 对列表选择项进行排序
lb2 = wx.ListBox(panel, choices=list2, style=wx.LB_EXTENDED)
self.Bind(wx.EVT_LISTBOX, self.on_listbox2, lb2)
hbox1 = wx.BoxSizer()
hbox1.Add(st1, proportion=1, flag=wx.LEFT | wx.RIGHT, border=5)
hbox1.Add(lb1, proportion=1)
hbox2 = wx.BoxSizer()
hbox2.Add(st2, proportion=1, flag=wx.LEFT | wx.RIGHT, border=5)
hbox2.Add(lb2, proportion=1)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(hbox1, flag=wx.ALL | wx.EXPAND, border=5)
vbox.Add(hbox2, flag=wx.ALL | wx.EXPAND, border=5)
panel.SetSizer(vbox)
def on_listbox1(self, event):
listbox = event.GetEventObject()
print("选择{0}".format(listbox.GetSelection()))
def on_listbox2(self, event):
listbox = event.GetEventObject()
print("选择{0}".format(listbox.GetSelections()))
app = wx.App() # 创建应用程序对象
frm = MyFrame() # 创建窗口对象
frm.Show() # 显示窗口
app.MainLoop() # 进入主事件循环
4.4 静态图片
静态图片控件用于显示一张图片, 图片可以是wx.Python所支持的任意图片格式, 静态图片控件类是wx.StaticBitmap。
在界面中实现两个按钮和一个静态图片控件, 在单击按钮时显示不同的图片:
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="静态图片控件", size=(300, 300))
self.panel = wx.Panel(parent=self)
# 创建wx.Bitmap图片对象列表
self.bmps = [wx.Bitmap('pic/lena.png', wx.BITMAP_TYPE_PNG),
wx.Bitmap('pic/lena_c.bmp', wx.BITMAP_TYPE_BMP),
wx.Bitmap('pic/output.bmp', wx.BITMAP_TYPE_BMP)]
b1 = wx.Button(self.panel, id=1, label='Button1')
b2 = wx.Button(self.panel, id=2, label='Button2')
self.Bind(wx.EVT_BUTTON, self.on_click, id=1, id2=2)
# 静态图片控件
self.image = wx.StaticBitmap(self.panel, bitmap=self.bmps[0])
# 创建垂直方向的布局管理器对象vbox
vbox = wx.BoxSizer(wx.VERTICAL)
# 添加标控件到布局管理器对象vbox
vbox.Add(b1, proportion=1, flag=wx.EXPAND)
vbox.Add(b2, proportion=1, flag=wx.EXPAND)
vbox.Add(self.image, proportion=3, flag=wx.EXPAND)
self.panel.SetSizer(vbox)
def on_click(self, event):
event_id = event.GetId()
if event_id == 1:
self.image.SetBitmap(self.bmps[1])
else:
self.image.SetBitmap(self.bmps[2])
# 重新设置panel面板布局,因为图片替换后需要重写绘制窗口
self.panel.Layout()
app = wx.App() # 创建应用程序对象
frm = MyFrame() # 创建窗口对象
frm.Show() # 显示窗口
app.MainLoop() # 进入主事件循环