微风扬起你的美 发表于 2024-9-11 19:31:14

Python使用everything库构建文件搜索和管理工具

项目概述

这个工具的主要功能包括:

[*]文件搜索:用户可以输入关键字来搜索文件。
[*]文件管理:用户可以查看搜索结果,选择文件并将其添加到管理列表。
[*]数据导出:用户可以将管理列表中的文件信息导出为 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:
      #             iflnk_path.endswith('.lnk'):
      #               shortcut = shell.CreateShortCut(lnk_path)
      #               target_path = shortcut.Targetpath
      #               caption = os.path.splitext(os.path.basename(lnk_path))
      #             else:
      #               # 处理非 .lnk 文件,直接使用文件路径
      #               target_path = lnk_path
      #               caption = os.path.splitext(os.path.basename(lnk_path))

      #             file.write(f"\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))

                  file.write(f"\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)
    #         if index != -1:# 确保索引有效
    #             self.list_ctrl1.SetItem(index, 1, item)
    #         else:
    #             wx.MessageBox(f"Failed to insert item {item}", "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文件搜索和管理的资料请关注脚本之家其它相关文章!

来源:https://www.jb51.net/python/3264613eu.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Python使用everything库构建文件搜索和管理工具