wxPython基础
wxPython简介
wxPython是Python语言的一套优秀的GUI图形库,允许Python程序员创建完整的,功能健全的GUI用户界面。wxPython是作为优秀的跨平台GUI库wxWidgets的Python封装和Python模块的方式提供给用户的。
wxPython基本操作
作为图形用户界面开发工具包,wxPython主要提供了如下内容
- 窗口
- 控件
- 事件处理
- 布局管理
创建窗口
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title="第一个GUI程序!", size=(400, 300))
self.Center() # 设置窗口居中
panel = wx.Panel(parent=self)
class App(wx.App):
def OnInit(self):
# 创建窗口对象
frame = MyFrame()
frame.Show()
return True
if __name__ == '__main__':
app = App()
app.MainLoop() # 进入主事件循环
事件处理
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='事件处理', size=(300, 180))
self.Center() # 设置窗口居中
panel = wx.Panel(parent=self)
self.statictext = wx.StaticText(parent=panel, pos=(110, 15))
#parent=panel表示把当前按钮放在面板中, id为当前按钮编号, label为按钮名, pos为按钮位置
b1 = wx.Button(parent=panel, id=10, label='Button1', pos=(100, 45))
b2 = wx.Button(parent=panel, id=11, label='Button2', pos=(100, 85))
#将事件与事件处理函数绑定
#EVT_BUTTON表示当前控件的时间类型, on_click表示触发该事件所调用的函数
#id = 10, id2 = 20表示绑定id为10-20的控件
self.Bind(wx.EVT_BUTTON, self.on_click, id=10, id2=20)
def on_click(self, event):
#获取当前事件的id号,根据id写对应的处理函数
event_id = event.GetId()
print(event_id)
if event_id == 10:
self.statictext.SetLabelText('Button1单击')
else:
self.statictext.SetLabelText('Button2单击')
class App(wx.App):
def OnInit(self):
# 创建窗口对象
frame = MyFrame()
frame.Show()
return True
if __name__ == '__main__':
app = App()
app.MainLoop() # 进入主事件循环
鼠标事件处理
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title="鼠标事件处理", size=(400, 300))
self.Centre() # 设置窗口居中
self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
self.Bind(wx.EVT_LEFT_UP, self.on_left_up)
self.Bind(wx.EVT_MOTION, self.on_mouse_move)
def on_left_down(self, evt):
print('鼠标按下')
def on_left_up(self, evt):
print('鼠标释放')
def on_mouse_move(self, event):
#如果按住鼠标移动,返回当前位置
if event.Dragging() and event.LeftIsDown():
pos = event.GetPosition()
print(pos)
class App(wx.App):
def OnInit(self):
# 创建窗口对象
frame = MyFrame()
frame.Show()
return True
if __name__ == '__main__':
app = App()
app.MainLoop() # 进入主事件循环
布局管理器
Box布局器
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='StaticBox布局', size=(400, 300))
self.Center() # 设置窗口居中
panel = wx.Panel(parent=self)
# 创建垂直方向的Box布局管理器对象
vbox = wx.BoxSizer(wx.VERTICAL)
self.statictext = wx.StaticText(parent=panel, label='Button1单击')
# 添加静态文本到Box布局管理器
#proportion表示当前空间所占的比例, flag用来设置当前控件的位置,边框,尺寸参数, border表示边界的宽度
vbox.Add(self.statictext, proportion=2, flag=wx.FIXED_MINSIZE | wx.TOP | wx.ALIGN_CENTER, border=10)
b1 = wx.Button(parent=panel, id=10, label='Button1')
b2 = wx.Button(parent=panel, id=11, label='Button2')
self.Bind(wx.EVT_BUTTON, self.on_click, id=10, id2=20)
# 创建静态框对象
sb = wx.StaticBox(panel, label="按钮框")
# 创建水平方向的StaticBox布局管理器
hsbox = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
# 添加b1到水平StaticBox布局管理
hsbox.Add(b1, 0, wx.EXPAND | wx.BOTTOM, 5)
# 添加b2到水平StaticBox布局管理
hsbox.Add(b2, 0, wx.EXPAND | wx.BOTTOM, 5)
# 添加hbox到vbox
vbox.Add(hsbox, proportion=1, flag=wx.CENTER)
#将布局管理器放入面板中
panel.SetSizer(vbox)
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单击')
class App(wx.App):
def OnInit(self):
# 创建窗口对象
frame = MyFrame()
frame.Show()
return True
if __name__ == '__main__':
app = App()
app.MainLoop() # 进入主事件循环
FlexGrid布局器
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='FlexGrid布局', size=(400, 200))
self.Centre() # 设置窗口居中
panel = wx.Panel(parent=self)
#创建3×2大小的网格管理器,边界大小为10
fgs = wx.FlexGridSizer(3, 2, 10, 10)
#
title = wx.StaticText(panel, label="标题:")
author = wx.StaticText(panel, label="作者名:")
review = wx.StaticText(panel, label="内容:")
tc1 = wx.TextCtrl(panel)
tc2 = wx.TextCtrl(panel)
#style代表窗口风格,TE_MULTILINE代表是多行格式的
tc3 = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
fgs.AddMany([title, (tc1, 1, wx.EXPAND),
author, (tc2, 1, wx.EXPAND),
review, (tc3, 1, wx.EXPAND)])
#设置控件所占行和列的比例
fgs.AddGrowableRow(0, 1)
fgs.AddGrowableRow(1, 1)
fgs.AddGrowableRow(2, 3)
fgs.AddGrowableCol(0, 1)
fgs.AddGrowableCol(1, 2)
#把当前网格管理器放入一个水平Box管理器中,防止一些内容越界的问题,不是必要
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(fgs, proportion=1, flag=wx.ALL | wx.EXPAND, border=15)
#将Box管理器放入面板中
panel.SetSizer(hbox)
class App(wx.App):
def OnInit(self):
# 创建窗口对象
frame = MyFrame()
frame.Show()
return True
if __name__ == '__main__':
app = App()
app.MainLoop() # 进入主事件循环
常用控件
按钮
- wx.Button 普通按钮
- wx.ToggleButton 能进行状态切换的按钮,点一下就代表选中了
- wx.BitmapButton 带有图标的按钮
# coding=utf-8
# 代码文件:chapter19/ch19.6.1.py
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='静态文本和按钮', size=(300, 200))
self.Center() # 设置窗口居中
panel = wx.Panel(parent=self)
# 创建垂直方向的Box布局管理器
vbox = wx.BoxSizer(wx.VERTICAL)
self.statictext = wx.StaticText(parent=panel, label='锄禾日当午', style=wx.ALIGN_CENTRE_HORIZONTAL)
#创建三种类型的按钮
b1 = wx.Button(parent=panel,id = 1, label='OK')
b2 = wx.ToggleButton(panel, id = 2, label = 'ToggleButton')
bmp = wx.Bitmap('./images/flag/1.png', wx.BITMAP_TYPE_PNG)
b3 = wx.BitmapButton(panel, id = 3, bitmap = bmp)
self.Bind(wx.EVT_BUTTON, self.on_click, id = 1, id2 = 3)
# 添加静态文本和按钮到Box布局管理器
vbox.Add(100, 10, proportion=1, flag=wx.CENTER | wx.FIXED_MINSIZE) #填充空白
vbox.Add(self.statictext, proportion=1, flag=wx.CENTER | wx.FIXED_MINSIZE)
vbox.Add(b1, proportion=1, flag=wx.CENTER | wx.EXPAND)
vbox.Add(b2, proportion=1, flag=wx.CENTER | wx.EXPAND)
vbox.Add(b3, proportion=1, flag=wx.CENTER | wx.EXPAND)
panel.SetSizer(vbox)
def on_click(self, event):
self.statictext.SetLabelText('汗滴禾下土')
class App(wx.App):
def OnInit(self):
# 创建窗口对象
frame = MyFrame()
frame.Show()
return True
if __name__ == '__main__':
app = App()
app.MainLoop() # 进入主事件循环
单选按钮和复选框
- wx.RadioButton单选按钮
- wx.CheckButton复选框
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='复选框和单选按钮', size=(400, 130))
self.Center() # 设置窗口居中
panel = wx.Panel(self)
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
statictext = wx.StaticText(panel, label='选择你喜欢的编程语言:')
cb1 = wx.CheckBox(panel, 1, 'Python')
cb2 = wx.CheckBox(panel, 2, 'Java')
cb3 = wx.CheckBox(panel, 3, 'C++')
self.Bind(wx.EVT_CHECKBOX, self.on_checkbox_click, id=1, id2=3)
hbox1.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
hbox1.Add(cb1, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
hbox1.Add(cb2, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
hbox1.Add(cb3, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
statictext = wx.StaticText(panel, label='选择性别:')
#style = wx.RB_GROUP表示后续控件都归为1组
radio1 = wx.RadioButton(panel, 4, '男', style=wx.RB_GROUP)
radio2 = wx.RadioButton(panel, 5, '女')
self.Bind(wx.EVT_RADIOBUTTON, self.on_radio1_click, id=4, id2=5)
hbox2.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
hbox2.Add(radio1, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
hbox2.Add(radio2, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
hbox3 = wx.BoxSizer(wx.HORIZONTAL)
statictext = wx.StaticText(panel, label='选择你最喜欢吃的水果:')
radio3 = wx.RadioButton(panel, 6, '苹果', style=wx.RB_GROUP)
radio4 = wx.RadioButton(panel, 7, '橘子')
radio5 = wx.RadioButton(panel, 8, '香蕉')
self.Bind(wx.EVT_RADIOBUTTON, self.on_radio2_click, id=6, id2=8)
hbox3.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
hbox3.Add(radio3, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
hbox3.Add(radio4, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
hbox3.Add(radio5, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(hbox1, 1, flag=wx.ALL | wx.EXPAND, border=5)
vbox.Add(hbox2, 1, flag=wx.ALL | wx.EXPAND, border=5)
vbox.Add(hbox3, 1, flag=wx.ALL | wx.EXPAND, border=5)
panel.SetSizer(vbox)
def on_checkbox_click(self, event):
#获取当前事件的对象
cb = event.GetEventObject()
#输出对应label 和 状态(是否被选择)
print('选择 {0},状态{1}'.format(cb.GetLabel(), event.IsChecked()))
def on_radio1_click(self, event):
rb = event.GetEventObject()
print('第一组 {0} 被选中'.format(rb.GetLabel()))
def on_radio2_click(self, event):
rb = event.GetEventObject()
print('第二组 {0} 被选中'.format(rb.GetLabel()))
class App(wx.App):
def OnInit(self):
# 创建窗口对象
frame = MyFrame()
frame.Show()
return True
if __name__ == '__main__':
app = App()
app.MainLoop() # 进入主事件循环
下拉列表
- wx.ComboBox 文本框可修改
- wx.Choice 文本框不可修改
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='下拉列表', size=(400, 130))
self.Center() # 设置窗口居中
panel = wx.Panel(self)
#ComboBox下拉列表, 放到一个hbox中
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
statictext = wx.StaticText(panel, label='选择你喜欢的编程语言:')
list1 = ['Python', 'C++', 'Java']
#style = wx.CB_SORT 对列表进行排序
ch1 = wx.ComboBox(panel, -1, choices=list1, style=wx.CB_SORT)
self.Bind(wx.EVT_COMBOBOX, self.on_combobox, ch1)
hbox1.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
hbox1.Add(ch1, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
#Choice下拉列表, 放到一个hbox中
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
statictext = wx.StaticText(panel, label='选择性别:')
list2 = ['男', '女']
ch2 = wx.Choice(panel, -1, choices=list2)
self.Bind(wx.EVT_CHOICE, self.on_choice, ch2)
hbox2.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
hbox2.Add(ch2, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
#将两个hbox放到vbox中
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(hbox1, 1, flag=wx.ALL | wx.EXPAND, border=5)
vbox.Add(hbox2, 1, flag=wx.ALL | wx.EXPAND, border=5)
#vbox放入面板中
panel.SetSizer(vbox)
def on_combobox(self, event):
print('选择 {0}'.format(event.GetString()))
def on_choice(self, event):
print('选择 {0}'.format(event.GetString()))
class App(wx.App):
def OnInit(self):
# 创建窗口对象
frame = MyFrame()
frame.Show()
return True
if __name__ == '__main__':
app = App()
app.MainLoop() # 进入主事件循环