Python 使用everything的相关模块,创建极其快速的文件搜索和管理工具

news2024/11/15 15:36:53

在这篇博客中,我将分享如何使用 Python 的 everytools库构建一个简单的文件搜索和管理工具。这个工具允许用户搜索文件、查看文件路径、导出文件信息到 Excel,以及生成配置文件。
C:\pythoncode\new\everythingtools.py

项目概述

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

  • 文件搜索:用户可以输入关键字来搜索文件。
  • 文件管理:用户可以查看搜索结果,选择文件并将其添加到管理列表。
  • 数据导出:用户可以将管理列表中的文件信息导出为 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的基本用法,适合初学者学习和实践。通过这个项目,您可以了解如何处理用户输入、管理列表视图和文件操作等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2071334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql binlog 全量与增量备份

mysql binlog 全量与增量备份 mysql binlog常用操作 https://blog.csdn.net/xyy1028/article/details/124446625 mysqldump mysqlbinlog 增量备份 mysql的增量备份 https://blog.51cto.com/u_16213572/10976496 mysql全量备份与增量备份 — vip https://blog.51cto.com/hehe1…

Java学习_20_File以及IO流

文章目录 前言一、FileFile中常见的成员方法判断和获取创建和删除获取和遍历 二、IO流IO流体系结构字节流字节输出流:FileOutputStream字节输入流FileInputStrea文件拷贝try……catch异常处理中文乱码现象 字符流字符流读取FileReader字符流输出FileWriter底层原理 …

堆《数据结构》

堆《数据结构》 1. 堆排序1.1 建堆向上调整建堆向下调整建堆 1.2 利用堆删除思想来进行排序1.3Top-k问题 2.堆的时间复杂度 1. 堆排序 1.1 建堆 建大堆 建小堆 向上调整建堆 AdjustUp建堆 void AdjustUp(HPDataType* a, int child) {// 初始条件// 中间过程// 结束条件int p…

专利权和版权有什么区别?

专利权和版权有什么区别?

【IEEE】第四届智能通信与计算国际学术会议(ICICC 2024,10月18-20)

第四届智能通信与计算国际学术会议(ICICC 2024)将于2024年10月18-20日在中国郑州隆重举行。 会议旨在为从事智能通信与计算研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术,了解学术发展趋势,拓宽研究…

帆软报表,达梦数据库驱动上传失败

1、按照正常操作新建数据库连接,上传准备好的达梦驱动时,提示如图一需要修改SystemConfig.driverUpload为true才可以。 2、FineDB存储了数据决策系统中除平台属性配置以外的所有信息。详情请参见: FineDB 数据库简介。 3、因此管理员可通过…

都2024年了,你还在手动敲SQL吗?试试这款开源免费的AI数据库!

​ ✍️作为一名开发人员,基本上每天都要和数据库打交道,无论是设计表结构、执行查询还是调试应用中的数据问题。长期以来,我一直在使用诸如DBeaver、Navicat和DataGrip这样的数据库管理工具。尽管这些工具各有千秋,但在面对复杂的…

python怎么使用模块中的类

Chain.py是模块(Module),在代码里定义的Class Chain是在模块里定义的类。 一种方法是: from Chain import Chain 还有一种方法是: a Chain.Chain() 相当于从模块里索引出这个类,两种方法都可以。

3b1b自注意力机制讲解记录

本文是对视频【官方双语】直观解释注意力机制,Transformer的核心 | 【深度学习第6章】的整理 1 背景 要解决的问题:接收一段文本,预测下一个词 句子会被切成许多小块,这些小块称为token。token可以是单词也可以是词组。为了简单…

SpringBoot百万行Excel导入MySQL实践

在公司开发时,客户说需要支持大数据量excel导入,所以打算写一篇文章记录下思路和优化过程。 一、前期准备 首先我们选用的肯定是阿里出品的EasyExcel,对比poi和jxl占内存更少 easyexcel官方网站准备测试的数据库和excel文件,已经…

Zustand:让React状态管理更简单、更高效

Zustand 这个单词在德语里是状态的意思(发音:促stand) 1. 下载zustand npm i zustand 或者 yarn add zustand2.创建一个store import { create } from zustandconst useBearStore create((set) > ({bears: 0,increasePopulation: …

20240824给飞凌OK3588-C的核心板刷Ubuntu22.04并连接adb

20240824给飞凌OK3588-C的核心板刷Ubuntu22.04并连接adb 2024/8/24 15:56 缘起,由于我司对面积有极度的追求,所以将飞凌OK3588-C开发板使用的【9线】type-C接口(USB3.1?)降级为4线的USB2.0。 【micro USB/MINI USB。】 先决条件…

基于RK3588的多摄像头车辆与车道线检测系统(基于rk3588的车辆和车道线检测,可以带四个720p的摄像头,2个1080p的摄像头)

硬件配置: 处理器:Rockchip RK3588,这是一款高性能的嵌入式处理器,支持多路高清视频输入和处理。摄像头配置: 4个720p(1280x720)分辨率的摄像头2个1080p(1920x1080)分辨…

什么是持续集成(持续交付、部署)

文章目录 1 持续集成1.1 持续集成的好处1.2 持续集成的目的1.3 没有持续集成的状况 2 持续交付3 持续部署4 持续交付和持续部署的区别 1 持续集成 持续集成(Continuous integration,简称CI),简单来说持续集成就是频繁地&#xff…

拓扑排序,以及区间dp相关试题

目录 1.有向无环图(DAG图) 2.AOV网:顶点活动图 3.拓扑排序 4.实现拓扑排序 力扣.207课程表 牛客.最长回文子序列 1.有向无环图(DAG图) 入度:表示有多少条边指向它 出度:有多少条边向外指出他 2.AOV网:顶点活动图 3.拓扑排序 找到做事情的先后顺序 …

React学习笔记(三)——redux状态管理工具

1. Redux快速上手 1.1 什么是Redux? Redux 是 React 最常用的 集中状态管理工具 ,类似于 Vue 中的 Pinia(Vuex), 可以独立于框架运行 作用: 通过集中管理的方式管理应用的状态 1.2 Redux快速体验 不和任何…

【OpenGL学习笔记】--图像管线

图像管线(Image Pipeline)是计算机图形学中一个核心概念,尤其是在图形处理和渲染的上下文中。它是一个用于处理和渲染图像的流程,其中包括从场景数据的输入到最终图像输出的各个阶段。 图像管线的组成 顶点处理(Verte…

大模型入门到精通——使用Embedding API及搭建本地知识库(一)

使用Embedding API及搭建本地知识库 1. 基于智谱AI调用Embedding API实现词向量编码 首先,生成.env 文件,填写好智谱AI的API-key 参考:大模型入门到实战——基于智谱API key 调用大模型文本生成 读取本地/项目的环境变量。 find_dotenv(…

基于SSM的在线家教管理系统的设计与实现 (含源码+sql+视频导入教程+论文+PPT)

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的在线家教管理系统拥有三个角色 管理员:用户管理、教师管理、简历管理、申请管理、课程管理、招聘教师管理、应聘管理、评价管理等 教师:课程管理、应聘…

Prometheus Operator部署管理

Prometheus Operator部署管理 Prometheus Operator & Kube-Prometheus & Helm chart 部署区别 Prometheus Operator 是 Kubernetes 原生的工具,它通过将 Prometheus 资源定义为 Kubernetes 对象(CRD)来简化 Prometheus 集群的管理。…