项目概述
这个工具的主要功能包括:
- 文件搜索:用户可以输入关键字来搜索文件。
- 文件管理:用户可以查看搜索结果,选择文件并将其添加到管理列表。
- 数据导出:用户可以将管理列表中的文件信息导出为 Excel 文件。
- 配置文件生成:用户可以生成配置文件,方便后续使用。
环境准备
确保安装了以下库:
1 | pip install wxPython pandas pywin32,everytools |
代码实现
以下是完整的代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | 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 = clGreenn") # file.write("width = 150n") # file.write("height = 70nn") # 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 = clGreenn" ) file .write( "width = 150n" ) file .write( "height = 70nn" ) 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文件搜索和管理的资料请关注IT俱乐部其它相关文章!