项目概述
这个工具的主要功能包括:
- 文件搜索:用户可以输入关键字来搜索文件。
- 文件管理:用户可以查看搜索结果,选择文件并将其添加到管理列表。
- 数据导出:用户可以将管理列表中的文件信息导出为 excel 文件。
- 配置文件生成:用户可以生成配置文件,方便后续使用。
环境准备
确保安装了以下库:
pip install wxpython pandas pywin32,everytools
代码实现
以下是完整的代码实现:
import wx
from everytools import everytools
import pandas as pd
import os
import pythoncom
import win32com.client
class myframe(wx.frame):
def __init__(self, *args, **kw):
super(myframe, self).__init__(*args, **kw)
self.initui()
self.all_items = [] # 用于存储listview1的所有项目
def initui(self):
panel = wx.panel(self)
vbox = wx.boxsizer(wx.vertical)
# 搜索框
self.search_ctrl = wx.textctrl(panel, style=wx.te_process_enter)
self.search_ctrl.bind(wx.evt_text_enter, self.onsearch)
# listview1
self.list_ctrl1 = wx.listctrl(panel, style=wx.lc_report)
self.list_ctrl1.insertcolumn(0, 'file name', width=200)
self.list_ctrl1.insertcolumn(1, 'file path', width=300)
self.list_ctrl1.bind(wx.evt_list_item_activated, self.onitemactivated)
# listview2
self.list_ctrl2 = wx.listctrl(panel, style=wx.lc_report)
self.list_ctrl2.insertcolumn(0, 'file name', width=200)
self.list_ctrl2.insertcolumn(1, 'file path', width=300)
# 导出excel按钮
self.export_button = wx.button(panel, label='export to excel')
self.export_button.bind(wx.evt_button, self.onexport)
# 生成配置文件按钮
self.config_button = wx.button(panel, label='generate config file')
self.config_button.bind(wx.evt_button, self.ongenerateconfig)
# 删除选中项按钮
self.delete_button = wx.button(panel, label='delete selected')
self.delete_button.bind(wx.evt_button, self.ondelete)
# 过滤框
self.filter_ctrl = wx.textctrl(panel, style=wx.te_process_enter)
self.filter_ctrl.sethint("search listview1...")
self.filter_ctrl.bind(wx.evt_text_enter, self.onfilterlistview)
# 布局
vbox.add(self.search_ctrl, 0, wx.expand | wx.all, 5)
vbox.add(self.filter_ctrl, 0, wx.expand | wx.all, 5)
vbox.add(self.list_ctrl1, 1, wx.expand | wx.all, 5)
vbox.add(self.list_ctrl2, 1, wx.expand | wx.all, 5)
vbox.add(self.export_button, 0, wx.expand | wx.all, 5)
vbox.add(self.config_button, 0, wx.expand | wx.all, 5)
vbox.add(self.delete_button, 0, wx.expand | wx.all, 5)
panel.setsizer(vbox)
self.settitle('file search and management')
self.centre()
def onsearch(self, event):
keyword = self.search_ctrl.getvalue()
es = everytools()
es.search(keyword)
try:
results = es.results()
if results.empty:
wx.messagebox("no results found.", "info", wx.ok | wx.icon_information)
return
except oserror as e:
wx.messagebox(f"error retrieving results: {e}", "error", wx.ok | wx.icon_error)
return
except exception as e:
wx.messagebox(f"an unexpected error occurred: {e}", "error", wx.ok | wx.icon_error)
return
if 'name' not in results.columns or 'path' not in results.columns:
wx.messagebox("expected columns 'name' or 'path' not found in results.", "error", wx.ok | wx.icon_error)
return
self.list_ctrl1.deleteallitems()
self.all_items = [] # 重置存储所有项目的列表
for index, row in results.iterrows():
self.list_ctrl1.insertitem(index, row['name'])
self.list_ctrl1.setitem(index, 1, row['path'])
self.all_items.append((row['name'], row['path'])) # 存储所有项目
def onitemactivated(self, event):
index = event.getindex()
file_name = self.list_ctrl1.getitemtext(index, 0)
file_path = self.list_ctrl1.getitemtext(index, 1)
self.list_ctrl2.insertitem(self.list_ctrl2.getitemcount(), file_name)
self.list_ctrl2.setitem(self.list_ctrl2.getitemcount() - 1, 1, file_path)
def onexport(self, event):
dialog = wx.dirdialog(none, "choose a directory to save the excel file:", style=wx.dd_default_style)
if dialog.showmodal() == wx.id_ok:
directory = dialog.getpath()
file_path = f"{directory}/exported_files.xlsx"
data = []
for i in range(self.list_ctrl2.getitemcount()):
data.append({
'file name': self.list_ctrl2.getitemtext(i, 0),
'file path': self.list_ctrl2.getitemtext(i, 1)
})
df = pd.dataframe(data)
df.to_excel(file_path, index=false)
wx.messagebox(f"data exported successfully to {file_path}", "info", wx.ok | wx.icon_information)
dialog.destroy()
def ongenerateconfig(self, event):
dialog = wx.dirdialog(none, "choose a directory to save the config file:", style=wx.dd_default_style)
if dialog.showmodal() == wx.id_ok:
directory = dialog.getpath()
file_path = os.path.join(directory, "buttons.ini")
self.exporttoini(file_path)
wx.messagebox(f"config file generated successfully at {file_path}", "info", wx.ok | wx.icon_information)
dialog.destroy()
def exporttoini(self, path):
shell = win32com.client.dispatch("wscript.shell")
# with open(path, 'w') as file:
# for idx, lnk_path in enumerate(self.get_selected_file_paths(), start=1):
# try:
# if lnk_path.endswith('.lnk'):
# shortcut = shell.createshortcut(lnk_path)
# target_path = shortcut.targetpath
# caption = os.path.splitext(os.path.basename(lnk_path))[0]
# else:
# # 处理非 .lnk 文件,直接使用文件路径
# target_path = lnk_path
# caption = os.path.splitext(os.path.basename(lnk_path))[0]
# file.write(f"[button{idx}]\n")
# file.write(f"caption = {caption}\n")
# file.write(f"link = {target_path}\n")
# file.write("color = clgreen\n")
# file.write("width = 150\n")
# file.write("height = 70\n\n")
# except exception as e:
# wx.messagebox(f"error processing file {lnk_path}: {e}", "error", wx.ok | wx.icon_error)
with open(path, 'w') as file:
for idx, lnk_path in enumerate(self.get_selected_file_paths(), start=1):
try:
if lnk_path.lower().endswith('.lnk'): # 判断文件名后缀是否为".lnk"
shortcut = shell.createshortcut(lnk_path)
target_path = shortcut.targetpath
else:
target_path = lnk_path
caption = os.path.splitext(os.path.basename(lnk_path))[0]
file.write(f"[button{idx}]\n")
file.write(f"caption = {caption}\n")
file.write(f"link = {target_path}\n")
file.write("color = clgreen\n")
file.write("width = 150\n")
file.write("height = 70\n\n")
except exception as e:
wx.messagebox(f"error processing file {lnk_path}: {e}", "error", wx.ok | wx.icon_error)
# def get_selected_file_paths(self):
# """获取所有选定的文件路径"""
# file_paths = []
# for i in range(self.list_ctrl2.getitemcount()):
# file_paths.append(self.list_ctrl2.getitemtext(i, 1))
# return file_paths
def get_selected_file_paths(self):
"""获取所有选定的文件路径,包含文件名"""
file_paths = []
for i in range(self.list_ctrl2.getitemcount()):
directory_path = self.list_ctrl2.getitemtext(i, 1) # 假设第0列是目录路径
file_name = self.list_ctrl2.getitemtext(i, 0) # 假设第1列是文件名
full_path = os.path.join(directory_path, file_name)
file_paths.append(full_path)
return file_paths
def ondelete(self, event):
selected = self.list_ctrl2.getfirstselected()
while selected != -1:
self.list_ctrl2.deleteitem(selected)
selected = self.list_ctrl2.getfirstselected()
def resolve_shortcut(self, path):
"""解析 .lnk 文件,返回它指向的可执行文件完整路径(包含exe名称)"""
shell = win32com.client.dispatch("wscript.shell")
shortcut = shell.createshortcut(path)
return shortcut.targetpath
# def onfilterlistview(self, event):
# filter_text = self.filter_ctrl.getvalue().lower()
# self.list_ctrl1.deleteallitems()
# for index, (name, path) in enumerate(self.all_items):
# if filter_text in name.lower() or filter_text in path.lower():
# self.list_ctrl1.insertitem(index, name)
# self.list_ctrl1.setitem(index, 1, path)
# def onfilterlistview(self):
# filtered_items = self.filter_items_based_on_some_criteria()
# self.list_ctrl1.deleteallitems()
# for item in filtered_items:
# index = self.list_ctrl1.insertitem(self.list_ctrl1.getitemcount(), item[0])
# if index != -1: # 确保索引有效
# self.list_ctrl1.setitem(index, 1, item[1])
# else:
# wx.messagebox(f"failed to insert item {item[0]}", "error", wx.ok | wx.icon_error)
# def onfilterlistview(self, event):
# # 从过滤框获取输入的过滤条件
# filter_text = self.filter_ctrl.getvalue().lower()
# # 清空list_ctrl1中的所有项目
# self.list_ctrl1.deleteallitems()
# # 遍历所有项目,找到与过滤条件匹配的项目并重新添加到list_ctrl1中
# for index, (name, path) in enumerate(self.all_items):
# if filter_text in name.lower() or filter_text in path.lower():
# self.list_ctrl1.insertitem(index, name)
# self.list_ctrl1.setitem(index, 1, path)
def onfilterlistview(self, event):
# 从过滤框获取输入的过滤条件
filter_text = self.filter_ctrl.getvalue().lower()
# 清空list_ctrl1中的所有项目
self.list_ctrl1.deleteallitems()
# 遍历所有项目,找到与过滤条件匹配的项目并重新添加到list_ctrl1中
for name, path in self.all_items:
if filter_text in name.lower() or filter_text in path.lower():
# 使用insertitem返回的index
new_index = self.list_ctrl1.insertitem(self.list_ctrl1.getitemcount(), name)
# 使用返回的index设置第二列
self.list_ctrl1.setitem(new_index, 1, path)
def main():
app = wx.app()
frame = myframe(none)
frame.show()
app.mainloop()
if __name__ == '__main__':
main()
代码解析
界面布局
代码使用 wx.boxsizer 来布局界面组件,包括搜索框、两个列表视图和多个按钮。每个组件都有相应的事件绑定,用于处理用户交互。
文件搜索功能
用户在搜索框中输入关键字,按下回车后,程序会调用 everytools 类进行搜索,并将结果显示在第一个列表视图中。如果没有找到结果,程序会弹出提示框。
文件管理功能
用户可以通过双击搜索结果,将文件添加到第二个列表视图中。选中的文件可以被删除。
数据导出与配置文件生成
用户可以将第二个列表视图中的文件信息导出为 excel 文件,或生成配置文件。
结果如下

总结
这个简单的文件搜索和管理工具展示了 everytools的基本用法,适合初学者学习和实践。通过这个项目,您可以了解如何处理用户输入、管理列表视图和文件操作等。
以上就是python使用everything库构建文件搜索和管理工具的详细内容,更多关于python everything文件搜索和管理的资料请关注代码网其它相关文章!
发表评论