1 需求
2 接口
3 示例

import wx
from pubsub import pub
class MainFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.init_ui()
# 窗口居中
self.Center()
# 窗口默认最大化
self.Maximize()
def init_ui(self):
# 创建 菜单栏
self.create_menu_bar()
# 创建 工具栏
self.create_tool_bar()
# 创建 主面板
self.create_main_panel()
# 创建 状态栏
self.create_status_bar()
def create_menu_bar(self):
# 创建 菜单栏
menu_bar = wx.MenuBar()
# 创建 File菜单 及其 Exit子菜单
file_menu = wx.Menu()
exit_item = file_menu.Append(wx.ID_EXIT, "Exit")
menu_bar.Append(file_menu, "File")
# 创建 Setting菜单 及其 Tool Setting、Scan Setting子菜单
setting_menu = wx.Menu()
tool_setting_item = setting_menu.Append(wx.ID_ANY, "Tool Setting")
setting_menu.AppendSeparator()
scan_setting_item = setting_menu.Append(wx.ID_ANY, "Scan Setting")
menu_bar.Append(setting_menu, "Setting")
# 创建 Tool菜单 及其 New Scan子菜单
tool_menu = wx.Menu()
new_scan_item = tool_menu.Append(wx.ID_ANY, "New Scan")
menu_bar.Append(tool_menu, "Tool")
# 创建 Help菜单 及其 About子菜单
help_menu = wx.Menu()
about_item = help_menu.Append(wx.ID_ABOUT, "About")
menu_bar.Append(help_menu, "Help")
# 设置 菜单栏
self.SetMenuBar(menu_bar)
# 绑定菜单项事件
self.Bind(wx.EVT_MENU, self.on_exit, exit_item)
self.Bind(wx.EVT_MENU, self.on_about, about_item)
def create_tool_bar(self):
tool_bar = self.CreateToolBar()
exit_tool = tool_bar.AddTool(wx.ID_EXIT, "Exit", wx.ArtProvider.GetBitmap(wx.ART_QUIT))
tool_bar.Realize()
self.Bind(wx.EVT_TOOL, self.on_exit, exit_tool)
def create_main_panel(self):
panel = wx.Panel(self)
main_sizer = wx.BoxSizer(wx.VERTICAL)
# 工具栏分割线
toolbar_divider = wx.StaticLine(panel, style=wx.LI_HORIZONTAL)
main_sizer.Add(toolbar_divider, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 1)
# 按钮区域
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
scan_btn = wx.Button(panel, label="开始扫描")
report_btn = wx.Button(panel, label="查看报告")
btn_sizer.Add(scan_btn, 0, wx.ALL, 5)
btn_sizer.Add(report_btn, 0, wx.ALL, 5)
main_sizer.Add(btn_sizer, 0, wx.ALL | wx.ALIGN_CENTER, 5)
# 日志区域
log_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.log_text_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.TE_READONLY)
log_sizer.Add(self.log_text_ctrl, 1, wx.EXPAND, 5)
main_sizer.Add(log_sizer, 1, wx.ALL | wx.EXPAND, 5)
#
panel.SetSizer(main_sizer)
# 绑定按钮事件
scan_btn.Bind(wx.EVT_BUTTON, self.on_scan)
report_btn.Bind(wx.EVT_BUTTON, self.on_report)
# 订阅日志更新
pub.subscribe(self.update_log_text_ctrl, "ui_log")
def create_status_bar(self):
status_bar = self.CreateStatusBar()
status_bar.SetStatusText("ready")
def on_exit(self, event):
self.Close(True)
def on_about(self, event):
dlg = wx.MessageDialog(self, "V0.1.20250827", "Version", wx.OK)
dlg.ShowModal()
dlg.Destroy()
def on_scan(self, event):
print("new scan")
def on_report(self, event):
print("report")
def update_log_text_ctrl(self, message):
self.log_text_ctrl.AppendText(message)
# 自动滚动到最新内容
self.log_text_ctrl.ShowPosition(self.log_text_ctrl.GetLastPosition())
def ui():
app = wx.App()
frame = MainFrame(None, title="wxPython Demo")
frame.Show()
app.MainLoop()
if __name__ == "__main__":
ui()
3 示例

import wx
from pubsub import pub
class MainFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.init_ui()
# 窗口居中
self.Center()
# 窗口默认最大化
self.Maximize()
def init_ui(self):
# 创建 菜单栏
self.create_menu_bar()
# 创建 工具栏
self.create_tool_bar()
# 创建 主面板
self.create_main_panel()
# 创建 状态栏
self.create_status_bar()
def create_menu_bar(self):
# 创建 菜单栏
menu_bar = wx.MenuBar()
# 创建 File菜单 及其 Exit子菜单
file_menu = wx.Menu()
exit_item = file_menu.Append(wx.ID_EXIT, "Exit")
menu_bar.Append(file_menu, "File")
# 创建 Setting菜单 及其 Tool Setting、Scan Setting子菜单
setting_menu = wx.Menu()
tool_setting_item = setting_menu.Append(wx.ID_ANY, "Tool Setting")
setting_menu.AppendSeparator()
scan_setting_item = setting_menu.Append(wx.ID_ANY, "Scan Setting")
menu_bar.Append(setting_menu, "Setting")
# 创建 Tool菜单 及其 New Scan子菜单
tool_menu = wx.Menu()
new_scan_item = tool_menu.Append(wx.ID_ANY, "New Scan")
menu_bar.Append(tool_menu, "Tool")
# 创建 Help菜单 及其 About子菜单
help_menu = wx.Menu()
about_item = help_menu.Append(wx.ID_ABOUT, "About")
menu_bar.Append(help_menu, "Help")
# 设置 菜单栏
self.SetMenuBar(menu_bar)
# 绑定菜单项事件
self.Bind(wx.EVT_MENU, self.on_exit, exit_item)
self.Bind(wx.EVT_MENU, self.on_about, about_item)
def create_tool_bar(self):
tool_bar = self.CreateToolBar()
exit_tool = tool_bar.AddTool(wx.ID_EXIT, "Exit", wx.ArtProvider.GetBitmap(wx.ART_QUIT))
tool_bar.Realize()
self.Bind(wx.EVT_TOOL, self.on_exit, exit_tool)
def create_main_panel(self):
panel = wx.Panel(self)
main_sizer = wx.BoxSizer(wx.VERTICAL)
# 工具栏分割线
toolbar_divider = wx.StaticLine(panel, style=wx.LI_HORIZONTAL)
main_sizer.Add(toolbar_divider, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 1)
# 日志区域1
log_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.log_text_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.TE_READONLY)
log_sizer.Add(self.log_text_ctrl, 1, wx.EXPAND, 5)
main_sizer.Add(log_sizer, 2, wx.ALL | wx.EXPAND, 5)
# 按钮区域
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
scan_btn = wx.Button(panel, label="开始扫描")
report_btn = wx.Button(panel, label="查看报告")
btn_sizer.Add(scan_btn, 0, wx.ALL, 5)
btn_sizer.Add(report_btn, 0, wx.ALL, 5)
main_sizer.Add(btn_sizer, 0, wx.ALL | wx.ALIGN_CENTER, 5)
# 日志区域2
lsof_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.lsof_text_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.TE_READONLY)
lsof_sizer.Add(self.lsof_text_ctrl, 1, wx.EXPAND, 5)
main_sizer.Add(lsof_sizer, 1, wx.ALL | wx.EXPAND, 5)
#
panel.SetSizer(main_sizer)
# 绑定按钮事件
scan_btn.Bind(wx.EVT_BUTTON, self.on_scan)
report_btn.Bind(wx.EVT_BUTTON, self.on_report)
# 订阅日志更新
pub.subscribe(self.update_log_text_ctrl, "ui_log")
def create_status_bar(self):
status_bar = self.CreateStatusBar()
status_bar.SetStatusText("ready")
def on_exit(self, event):
self.Close(True)
def on_about(self, event):
dlg = wx.MessageDialog(self, "V0.1.20250827", "Version", wx.OK)
dlg.ShowModal()
dlg.Destroy()
def on_scan(self, event):
print("new scan")
def on_report(self, event):
print("report")
def update_log_text_ctrl(self, message):
self.log_text_ctrl.AppendText(message)
# 自动滚动到最新内容
self.log_text_ctrl.ShowPosition(self.log_text_ctrl.GetLastPosition())
def ui():
app = wx.App()
frame = MainFrame(None, title="wxPython Demo")
frame.Show()
app.MainLoop()
if __name__ == "__main__":
ui()
4 参考资料