原文链接:http://www.juzicode.com/python-module-wxpython/
wxPython是基于wxWidgets的Python GUI框架,提供原生外观组件,支持Windows/macOS/Linux跨平台开发,适合需要专业级桌面应用程序的场景。
应用场景
- 企业级桌面应用
- 数据可视化仪表盘
- 跨平台系统工具
- 工业控制界面
- 多媒体播放器
- 科学计算前端
安装与导入
# juzicode.com/VX公众号:juzicode
pip install wxPython
import wx
注意安装模块的名称和导入模块的名称之间的差异。
使用方法
1. 创建基础窗口
初始化应用程序对象,创建主窗口并添加基础组件。Frame是窗口容器,Panel用于组织控件。Show方法显示窗口,MainLoop启动事件循环。
# juzicode.com/VX公众号:juzicode
import wx
class MyFrame(wx.Frame):
def__init__(self):
super().__init__(None, title="基础窗口")
panel = wx.Panel(self)
wx.StaticText(panel, label="欢迎使用wxPython", pos=(20,20))
self.SetSize(400,300)
self.Centre()
app = wx.App()
frame = MyFrame()
frame.Show()
app.MainLoop()
运行结果:
显示带标题的400x300窗口,包含欢迎文本

2. 按钮事件处理
绑定按钮点击事件,演示事件驱动编程。Bind方法关联事件类型与处理函数,事件对象包含交互信息。
# juzicode.com/VX公众号:juzicode
import wx
class EventFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="事件示例")
panel = wx.Panel(self)
self.btn = wx.Button(panel, label="点击计数", pos=(20,20))
self.count =0
self.btn.Bind(wx.EVT_BUTTON, self.on_click)
self.SetSize(300,200)
def on_click(self, event):
self.count +=1
self.btn.SetLabel(f"已点击 {self.count} 次")
app = wx.App()
frame = EventFrame()
frame.Show()
app.MainLoop()
运行结果:
按钮点击后更新计数显示

3. 布局管理器
使用BoxSizer实现自动布局。Add方法添加组件并指定比例,Flag参数控制对齐方式和边距。
# juzicode.com/VX公众号:juzicode
import wx
class LayoutFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="布局示例")
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.text_ctrl = wx.TextCtrl(panel)
btn_ok = wx.Button(panel, label="确定")
btn_cancel = wx.Button(panel, label="取消")
sizer.Add(self.text_ctrl,0, wx.EXPAND|wx.ALL,10)
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
btn_sizer.Add(btn_ok,0, wx.RIGHT,10)
btn_sizer.Add(btn_cancel,0)
sizer.Add(btn_sizer,0, wx.ALIGN_RIGHT|wx.ALL,10)
panel.SetSizer(sizer)
self.SetSize(400,200)
self.Centre()
app = wx.App()
frame = LayoutFrame()
frame.Show()
app.MainLoop()
运行结果:
显示带输入框和右侧按钮组的自适应布局窗口

4. 文件选择对话框
集成系统原生文件对话框,支持多选和格式过滤。FileDialog的样式参数控制对话框行为。
# juzicode.com/VX公众号:juzicode
import wx
class FileFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="文件对话框")
panel = wx.Panel(self)
btn = wx.Button(panel, label="选择文件")
btn.Bind(wx.EVT_BUTTON, self.on_open)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(btn,0, wx.ALL,20)
panel.SetSizer(sizer)
self.SetSize(300,200)
def on_open(self, event):
with wx.FileDialog(self,"打开文件", wildcard="文本文件 (*.txt)|*.txt",
style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)as dlg:
if dlg.ShowModal()== wx.ID_OK:
print("选中文件:", dlg.GetPath())
app = wx.App()
frame = FileFrame()
frame.Show()
app.MainLoop()
运行结果:
弹出系统文件选择对话框,选中后输出路径

5. 自定义绘图
使用PaintDC进行自定义绘图,实现数据可视化。绑定EVT_PAINT事件处理窗口重绘。
import wx
class DrawFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="绘图示例")
self.Bind(wx.EVT_PAINT, self.on_paint)
self.SetSize(400,300)
def on_paint(self, event):
dc = wx.PaintDC(self)
dc.SetPen(wx.Pen("blue",2))
dc.DrawLine(50,50,350,250)
dc.DrawCircle(200,150,50)
app = wx.App()
frame = DrawFrame()
frame.Show()
app.MainLoop()
运行结果:
窗口绘制蓝色对角线和圆形

6. 多线程处理
使用wx.CallAfter实现线程安全更新UI,避免界面冻结。演示后台任务处理模式。
# juzicode.com/VX公众号:juzicode
import threading,wx
class WorkerFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="多线程示例")
panel = wx.Panel(self)
self.gauge = wx.Gauge(panel,range=100)
btn = wx.Button(panel, label="开始任务")
btn.Bind(wx.EVT_BUTTON, self.on_start)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.gauge,0, wx.EXPAND|wx.ALL,20)
sizer.Add(btn,0, wx.CENTER|wx.BOTTOM,20)
panel.SetSizer(sizer)
self.SetSize(300,200)
def on_start(self, event):
threading.Thread(target=self.long_task).start()
def long_task(self):
for i inrange(101):
wx.CallAfter(self.gauge.SetValue, i)
wx.MilliSleep(50)
app = wx.App()
frame = WorkerFrame()
frame.Show()
app.MainLoop()
运行结果:
进度条平滑更新,界面保持响应

7.数据库集成
结合sqlite3展示数据绑定列表控件。ListCtrl显示数据库查询结果。
# juzicode.com/VX公众号:juzicode
import sqlite3
import wx
class DBFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="数据库示例")
self.list= wx.ListCtrl(self, style=wx.LC_REPORT)
self.list.InsertColumn(0,"ID", width=50)
self.list.InsertColumn(1,"姓名", width=100)
conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE users(id INTEGER, name TEXT)")
conn.executemany("INSERT INTO users VALUES(?,?)",
[(1,"张三"),(2,"李四")])
for row in conn.execute("SELECT * FROM users"):
index = self.list.InsertItem(self.list.GetItemCount(),str(row[0]))
self.list.SetItem(index,1, row[1])
self.SetSize(300,200)
app = wx.App()
frame = DBFrame()
frame.Show()
app.MainLoop()
运行结果:
列表显示数据库中的用户记录
