8
社区成员




import wx
import wx.lib.agw.aui as aui
import csv
import os
class AddressBookApp(wx.Frame):
def __init__(self, *args, **kw):
super(AddressBookApp, self).__init__(*args, **kw)
self.SetTitle("通讯录")
self.SetSize(900, 600)
# 使用内置图标
icon_bitmap = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION)
icon = wx.Icon()
icon.CopyFromBitmap(icon_bitmap)
self.SetIcon(icon)
# 创建 AuiManager
self.mgr = aui.AuiManager(self)
# 创建一个面板来放置树形视图
panel = wx.Panel(self)
self.tree = wx.ListCtrl(panel, style=wx.LC_REPORT)
self.tree.InsertColumn(0, '姓名', width=100)
self.tree.InsertColumn(1, '电话', width=100)
self.tree.InsertColumn(2, '微信', width=100)
self.tree.InsertColumn(3, '住址', width=550)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.tree, 1, wx.EXPAND | wx.ALL, 30) # 左右留 30 像素空隙
panel.SetSizer(sizer)
# 添加面板到 AuiManager
self.mgr.AddPane(panel, aui.AuiPaneInfo().Center().Caption("联系人列表").Resizable(True))
# 创建工具栏
toolbar = self.CreateToolBar()
# 使用内置图标
new_tool = toolbar.AddTool(wx.ID_NEW, "新建联系人", wx.ArtProvider.GetBitmap(wx.ART_NEW)) # 新建图标
open_tool = toolbar.AddTool(wx.ID_OPEN, "打开联系人", wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN)) # 打开图标
save_tool = toolbar.AddTool(wx.ID_SAVE, "保存联系人", wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE)) # 保存图标
edit_tool = toolbar.AddTool(wx.ID_EDIT, "编辑联系人", wx.ArtProvider.GetBitmap(wx.ART_EDIT)) # 编辑图标
delete_tool = toolbar.AddTool(wx.ID_DELETE, "删除联系人", wx.ArtProvider.GetBitmap(wx.ART_DELETE)) # 删除图标
toolbar.Realize()
# 给工具栏按钮添加提示功能
toolbar.SetToolShortHelp(new_tool.GetId(), "创建新联系人")
toolbar.SetToolShortHelp(open_tool.GetId(), "打开联系人文件")
toolbar.SetToolShortHelp(save_tool.GetId(), "保存联系人信息")
toolbar.SetToolShortHelp(edit_tool.GetId(), "编辑选中的联系人")
toolbar.SetToolShortHelp(delete_tool.GetId(), "删除选中的联系人")
# 绑定工具栏事件
self.Bind(wx.EVT_TOOL, self.on_add_contact, new_tool)
self.Bind(wx.EVT_TOOL, self.on_open_contact, open_tool)
self.Bind(wx.EVT_TOOL, self.on_save_contact, save_tool)
self.Bind(wx.EVT_TOOL, self.on_edit_contact, edit_tool)
self.Bind(wx.EVT_TOOL, self.on_delete_contact, delete_tool)
# 创建菜单栏
menu_bar = wx.MenuBar()
file_menu = wx.Menu()
file_menu.Append(wx.ID_NEW, "新建联系人")
file_menu.Append(wx.ID_OPEN, "打开联系人") # 添加打开选项
file_menu.Append(wx.ID_SAVE, "保存联系人") # 添加保存选项
file_menu.Append(wx.ID_EDIT, "编辑联系人")
file_menu.Append(wx.ID_DELETE, "删除联系人")
file_menu.AppendSeparator()
file_menu.Append(wx.ID_EXIT, "退出")
# 添加关于菜单
about_menu = wx.Menu()
about_menu.Append(wx.ID_ABOUT, "关于")
menu_bar.Append(file_menu, "文件")
menu_bar.Append(about_menu, "帮助")
self.SetMenuBar(menu_bar)
self.Bind(wx.EVT_MENU, self.on_exit, id=wx.ID_EXIT)
self.Bind(wx.EVT_MENU, self.on_open_contact, id=wx.ID_OPEN) # 绑定打开菜单
self.Bind(wx.EVT_MENU, self.on_save_contact, id=wx.ID_SAVE) # 绑定保存菜单
self.Bind(wx.EVT_MENU, self.on_about, id=wx.ID_ABOUT) # 绑定关于菜单
self.Bind(wx.EVT_CLOSE, self.on_close) # 绑定关闭事件
# 更新 AuiManager
self.mgr.Update()
def load_contacts(self):
"""从文件加载联系人信息"""
if os.path.exists("contacts.csv"): # 检查文件是否存在
self.tree.DeleteAllItems() # 清空现有列表项
with open("contacts.csv", mode="r", newline="", encoding="utf-8") as file:
reader = csv.reader(file)
for row in reader:
if len(row) == 4: # 确保正确数量的字段
index = self.tree.InsertItem(self.tree.GetItemCount(), row[0])
self.tree.SetStringItem(index, 1, row[1])
self.tree.SetStringItem(index, 2, row[2])
self.tree.SetStringItem(index, 3, row[3])
def on_add_contact(self, event):
self.contact_window("新建联系人")
def on_open_contact(self, event):
with wx.FileDialog(self, "打开联系人文件", wildcard="CSV files (*.csv)|*.csv",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDlg:
if fileDlg.ShowModal() == wx.ID_OK:
path = fileDlg.GetPath()
self.load_contacts_from_file(path)
def load_contacts_from_file(self, file_path):
"""从指定文件加载联系人信息"""
self.tree.DeleteAllItems() # 清空现有列表项
with open(file_path, mode="r", newline="", encoding="utf-8") as file:
reader = csv.reader(file)
for row in reader:
if len(row) == 4: # 确保正确数量的字段
index = self.tree.InsertItem(self.tree.GetItemCount(), row[0])
self.tree.SetStringItem(index, 1, row[1])
self.tree.SetStringItem(index, 2, row[2])
self.tree.SetStringItem(index, 3, row[3])
def on_save_contact(self, event):
self.save_contacts() # 保存联系人信息
wx.MessageBox("保存成功", "提示", wx.OK | wx.ICON_INFORMATION) # 显示保存成功消息
def save_contacts(self):
"""将联系人信息保存到文件"""
with open("contacts.csv", mode="w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
for i in range(self.tree.GetItemCount()):
row = [
self.tree.GetItemText(i, 0), # 姓名
self.tree.GetItemText(i, 1), # 电话
self.tree.GetItemText(i, 2), # 微信
self.tree.GetItemText(i, 3), # 住址
]
writer.writerow(row)
def on_edit_contact(self, event):
selected_index = self.tree.GetFirstSelected()
if selected_index == -1:
wx.MessageBox("请先选择一个联系人进行编辑", "无选择", wx.OK | wx.ICON_WARNING)
return
name = self.tree.GetItemText(selected_index, 0)
phone = self.tree.GetItemText(selected_index, 1)
wechat = self.tree.GetItemText(selected_index, 2)
address = self.tree.GetItemText(selected_index, 3)
self.contact_window("编辑联系人", name, phone, wechat, address, selected_index)
def on_delete_contact(self, event):
selected_index = self.tree.GetFirstSelected()
if selected_index == -1:
wx.MessageBox("请先选择一个联系人进行删除", "无选择", wx.OK | wx.ICON_WARNING)
return
self.tree.DeleteItem(selected_index)
def on_about(self, event):
wx.MessageBox("通讯录小程序\n版本 1.0\n作者: 传奇开心果", "关于", wx.OK | wx.ICON_INFORMATION)
def contact_window(self, title, name='', phone='', wechat='', address='', selected_index=None):
dialog = wx.Dialog(self, title=title, size=(400, 250))
wx.StaticText(dialog, label="姓名", pos=(20, 20))
wx.StaticText(dialog, label="电话", pos=(20, 60))
wx.StaticText(dialog, label="微信", pos=(20, 100))
wx.StaticText(dialog, label="住址", pos=(20, 140))
name_entry = wx.TextCtrl(dialog, value=name, pos=(100, 20))
phone_entry = wx.TextCtrl(dialog, value=phone, pos=(100, 60))
wechat_entry = wx.TextCtrl(dialog, value=wechat, pos=(100, 100))
address_entry = wx.TextCtrl(dialog, value=address, pos=(100, 140), size=(250, -1))
save_button = wx.Button(dialog, label="保存", pos=(150, 180))
save_button.Bind(wx.EVT_BUTTON, lambda event: self.save_contact(name_entry.GetValue(), phone_entry.GetValue(), wechat_entry.GetValue(), address_entry.GetValue(), dialog, selected_index))
dialog.ShowModal()
dialog.Destroy()
def save_contact(self, name, phone, wechat, address, dialog, selected_index=None):
if name and phone and wechat and address:
if selected_index is not None:
# 编辑联系人
self.tree.SetStringItem(selected_index, 0, name)
self.tree.SetStringItem(selected_index, 1, phone)
self.tree.SetStringItem(selected_index, 2, wechat)
self.tree.SetStringItem(selected_index, 3, address)
else:
# 新增联系人
index = self.tree.InsertItem(self.tree.GetItemCount(), name)
self.tree.SetStringItem(index, 1, phone)
self.tree.SetStringItem(index, 2, wechat)
self.tree.SetStringItem(index, 3, address)
dialog.Destroy()
else:
wx.MessageBox("请填写所有字段", "输入错误", wx.OK | wx.ICON_WARNING)
def on_exit(self, event):
self.Close()
def on_close(self, event):
self.mgr.UnInit()
self.Destroy()
if __name__ == '__main__':
app = wx.App(False)
frame = AddressBookApp(None)
frame.Show()
app.MainLoop()
这段代码实现了一个简单的通讯录应用程序,使用了 wxPython 库进行图形界面的开发。
下面对代码的主要部分进行逐步解释:
super(AddressBookApp, self).__init__(*args, **kw)
Copy Insert • 定义 AddressBookApp 类,继承自 wx.Frame,这是 GUI 应用程序的基础窗口类。 • init 构造函数中调用父类构造函数。 reader = csv.reader(file)
for row in reader:
if len(row) == 4: # 确保正确数量的字段
index = self.tree.InsertItem(self.tree.GetItemCount(), row[0])
self.tree.SetStringItem(index, 1, row[1])
self.tree.SetStringItem(index, 2, row[2])
self.tree.SetStringItem(index, 3, row[3])
Copy Insert • 从 CSV 文件加载联系人信息,并将其展示在列表控件中。 writer = csv.writer(file)
for i in range(self.tree.GetItemCount()):
row = [
self.tree.GetItemText(i, 0),
self.tree.GetItemText(i, 1),
self.tree.GetItemText(i, 2),
self.tree.GetItemText(i, 3),
]
writer.writerow(row)
Copy Insert • 将列表控件中显示的联系人信息保存到 CSV 文件中。 总结 这个简单的通讯录应用允许用户添加、编辑、删除和保存联系人信息。它利用 wxPython 库构建 GUI,使用 CSV 格式来保存联系人数据,提供一个直观的用户界面来管理联系人。