Python使用everything庫構(gòu)建文件搜索和管理工具
項目概述
這個工具的主要功能包括:
- 文件搜索:用戶可以輸入關(guān)鍵字來搜索文件。
- 文件管理:用戶可以查看搜索結(jié)果,選擇文件并將其添加到管理列表。
- 數(shù)據(jù)導(dǎo)出:用戶可以將管理列表中的文件信息導(dǎo)出為 Excel 文件。
- 配置文件生成:用戶可以生成配置文件,方便后續(xù)使用。
環(huán)境準備
確保安裝了以下庫:
pip install wxPython pandas pywin32,everytools
代碼實現(xiàn)
以下是完整的代碼實現(xiàn):
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)
# 導(dǎo)出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) # 假設(shè)第0列是目錄路徑
file_name = self.list_ctrl2.GetItemText(i, 0) # 假設(shè)第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 文件,返回它指向的可執(zhí)行文件完整路徑(包含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設(shè)置第二列
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 來布局界面組件,包括搜索框、兩個列表視圖和多個按鈕。每個組件都有相應(yīng)的事件綁定,用于處理用戶交互。
文件搜索功能
用戶在搜索框中輸入關(guān)鍵字,按下回車后,程序會調(diào)用 EveryTools 類進行搜索,并將結(jié)果顯示在第一個列表視圖中。如果沒有找到結(jié)果,程序會彈出提示框。
文件管理功能
用戶可以通過雙擊搜索結(jié)果,將文件添加到第二個列表視圖中。選中的文件可以被刪除。
數(shù)據(jù)導(dǎo)出與配置文件生成
用戶可以將第二個列表視圖中的文件信息導(dǎo)出為 Excel 文件,或生成配置文件。
結(jié)果如下

總結(jié)
這個簡單的文件搜索和管理工具展示了 everytools的基本用法,適合初學(xué)者學(xué)習(xí)和實踐。通過這個項目,您可以了解如何處理用戶輸入、管理列表視圖和文件操作等。
以上就是Python使用everything庫構(gòu)建文件搜索和管理工具的詳細內(nèi)容,更多關(guān)于Python everything文件搜索和管理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python 轉(zhuǎn)換文本編碼實現(xiàn)解析
這篇文章主要介紹了Python 轉(zhuǎn)換文本編碼實現(xiàn)解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值2019-08-08
關(guān)于Python中浮點數(shù)精度處理的技巧總結(jié)
雙精度浮點數(shù)(double)是計算機使用的一種數(shù)據(jù)類型,使用 64 位(8字節(jié)) 來存儲一個浮點數(shù)。下面這篇文章主要給大家總結(jié)介紹了關(guān)于Python中浮點數(shù)精度處理的技巧,需要的朋友可以參考借鑒,下面來一起看看吧。2017-08-08
win10下opencv-python特定版本手動安裝與pip自動安裝教程
這篇文章主要介紹了win10下opencv-python特定版本手動安裝與pip自動安裝教程,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
Python集成開發(fā)環(huán)境pycharm配置git的實現(xiàn)步驟
本文主要介紹了Python集成開發(fā)環(huán)境pycharm配置git的實現(xiàn)步驟,文中通過圖文的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05
scrapy redis配置文件setting參數(shù)詳解
這篇文章主要介紹了scrapy redis配置文件setting參數(shù)詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
python深度學(xué)習(xí)tensorflow入門基礎(chǔ)教程示例
這篇文章主要為大家介紹了python深度學(xué)習(xí)tensorflow入門基礎(chǔ)教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06

