python开发一个文件夹文件名提取工具(附完整代码)

 更新时间:2025年09月18日 09:13:14   作者:小庄-Python办公  
这篇文章主要为大家详细介绍了如何使用python开发一个文件夹文件名提取工具,专门用于提取文件夹中所有文件的名称并导出为Excel格式,感兴趣的小伙伴可以了解下

项目简介

这是一个基于PyQt5开发的桌面应用程序,专门用于提取文件夹中所有文件的名称并导出为Excel格式。该工具支持拖拽操作,提供直观的用户界面,能够递归遍历文件夹结构,是文件管理和数据整理的实用工具。

主要功能特性

核心功能

  • 拖拽支持:直接将文件夹拖拽到应用界面即可选择目标文件夹
  • 递归遍历:自动遍历文件夹及其所有子文件夹
  • 文件统计:统计并显示所有文件的详细信息
  • Excel导出:将文件列表导出为Excel格式,便于后续处理
  • 目录结构显示:按目录层级组织显示文件列表

用户体验

  • 可视化拖拽反馈:拖拽时提供绿色高亮效果
  • 实时状态提示:清晰的操作提示和状态反馈
  • 现代化界面:采用现代扁平化设计风格
  • 响应式布局:界面元素自适应窗口大小

技术架构

技术栈

  • GUI框架:PyQt5
  • 数据处理:pandas
  • 文件操作:Python标准库 (os, pathlib)
  • 开发语言:Python 3.x

核心组件

1. FileListWidget 类

class FileListWidget(QTextEdit):
    """支持拖拽的文本显示区域"""

主要职责:

  • 处理拖拽事件(dragEnterEvent, dragLeaveEvent, dragMoveEvent, dropEvent)
  • 验证拖拽内容是否为文件夹
  • 提供视觉反馈效果
  • 存储选中的文件夹路径

关键特性:

  • 跨平台兼容性:通过dragMoveEvent确保Windows平台的拖拽稳定性
  • 智能验证:只接受文件夹类型的拖拽,拒绝文件拖拽
  • 视觉反馈:拖拽进入时显示绿色边框和背景色

2. MainWindow 类

class MainWindow(QMainWindow):
    """主窗口类"""

主要职责:

  • 构建用户界面布局
  • 处理业务逻辑(文件遍历、数据处理)
  • 管理用户交互事件
  • 控制Excel导出功能

详细功能说明

拖拽功能实现

拖拽事件处理流程

  • dragEnterEvent:检测拖拽内容是否包含本地文件夹
  • dragMoveEvent:在Windows平台持续接受拖拽操作
  • dragLeaveEvent:恢复界面原始样式
  • dropEvent:处理文件夹路径并更新界面

关键代码解析

def dragEnterEvent(self, event: QDragEnterEvent):
    if event.mimeData().hasUrls():
        urls = event.mimeData().urls()
        accept = False
        if urls:
            for url in urls:
                if url.isLocalFile():
                    file_path = url.toLocalFile()
                    if os.path.isdir(file_path):
                        accept = True
                        break
        
        if accept:
            # 设置拖拽高亮样式
            self.setStyleSheet("""...""") 
            event.setDropAction(Qt.CopyAction)
            event.accept()

文件遍历算法

使用Python的os.walk()方法实现递归文件遍历:

def get_all_files(self, folder_path):
    file_list = []
    for root, dirs, files in os.walk(folder_path):
        relative_root = os.path.relpath(root, folder_path)
        if relative_root == '.':
            relative_root = '根目录'
        
        for file in files:
            file_list.append({
                '目录': relative_root,
                '文件名': file
            })
    return file_list

算法特点:

  • 递归遍历所有子目录
  • 记录文件的相对路径信息
  • 构建结构化数据便于后续处理

Excel导出功能

利用pandas库实现Excel导出:

def export_to_excel(self):
    df = pd.DataFrame(self.file_data)
    df.to_excel(file_path, index=False, sheet_name='文件列表')

导出特性:

  • 支持自定义保存路径
  • 包含目录和文件名两列数据
  • 提供操作成功/失败反馈

界面设计

布局结构

┌─────────────────────────────────────┐
│           应用标题                    │
├─────────────────────────────────────┤
│                                     │
│         拖拽区域                     │
│    (支持文件夹拖拽)                   │
│                                     │
├─────────────────────────────────────┤
│  [获取文件名]    [导出Excel]          │
├─────────────────────────────────────┤
│                                     │
│         结果显示区域                  │
│                                     │
└─────────────────────────────────────┘

样式设计

配色方案

  • 主色调:绿色系 (#4CAF50) - 代表成功和自然
  • 辅助色:蓝色系 (#2196F3) - 代表专业和信任
  • 背景色:浅灰色系 (#f0f0f0, #f9f9f9) - 提供舒适的视觉体验

交互反馈

  • 拖拽状态:绿色虚线边框 + 浅绿背景
  • 按钮悬停:颜色加深效果
  • 禁用状态:灰色显示

效果图

完整代码

import sys
import os
from pathlib import Path
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, 
    QWidget, QPushButton, QTextEdit, QLabel, QMessageBox,
    QFileDialog
)
from PyQt5.QtCore import Qt, QMimeData, QUrl
from PyQt5.QtGui import QDragEnterEvent, QDropEvent
import pandas as pd


class FileListWidget(QTextEdit):
    """支持拖拽的文本显示区域"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAcceptDrops(True)
        self.setReadOnly(True)
        self.setPlaceholderText("请将文件夹拖拽到此处...")
        self.folder_path = None
        
    def dragEnterEvent(self, event: QDragEnterEvent):
        print("拖拽进入事件触发")  # 调试信息
        if event.mimeData().hasUrls():
            urls = event.mimeData().urls()
            print(f"检测到URLs: {len(urls)}个")  # 调试信息
            
            accept = False
            if urls:
                for url in urls:
                    if url.isLocalFile():
                        file_path = url.toLocalFile()
                        print(f"检查路径: {file_path}")  # 调试信息
                        if os.path.isdir(file_path):
                            accept = True
                            break
            
            if accept:
                print("接受拖拽")  # 调试信息
                self.setStyleSheet("""
                    QTextEdit {
                        border: 2px dashed #4CAF50;
                        border-radius: 10px;
                        background-color: #e8f5e8;
                        font-size: 14px;
                        padding: 10px;
                    }
                """)
                event.setDropAction(Qt.CopyAction)
                event.accept()
            else:
                print("拒绝拖拽 - 没有可用的目录")  # 调试信息
                event.ignore()
        else:
            print("拒绝拖拽 - 没有URL数据")  # 调试信息
            event.ignore()
            
    def dragLeaveEvent(self, event):
        # 恢复原始样式
        self.setStyleSheet("""
            QTextEdit {
                border: 2px dashed #aaa;
                border-radius: 10px;
                background-color: #f9f9f9;
                font-size: 14px;
                padding: 10px;
            }
        """)
        super().dragLeaveEvent(event)
        
    def dragMoveEvent(self, event):
        # 某些平台需要在dragMoveEvent中持续接受拖拽
        if event.mimeData().hasUrls():
            for url in event.mimeData().urls():
                if url.isLocalFile() and os.path.isdir(url.toLocalFile()):
                    event.setDropAction(Qt.CopyAction)
                    event.accept()
                    return
        event.ignore()
            
    def dropEvent(self, event: QDropEvent):
        print("拖拽放下事件触发")  # 调试信息
        
        # 恢复原始样式
        self.setStyleSheet("""
            QTextEdit {
                border: 2px dashed #aaa;
                border-radius: 10px;
                background-color: #f9f9f9;
                font-size: 14px;
                padding: 10px;
            }
        """)
        
        urls = event.mimeData().urls()
        print(f"放下时检测到URLs: {len(urls) if urls else 0}个")  # 调试信息
        
        if urls:
            dropped_folder = None
            for url in urls:
                if url.isLocalFile():
                    p = url.toLocalFile()
                    print(f"放下的路径候选: {p}")  # 调试信息
                    if os.path.isdir(p):
                        dropped_folder = p
                        break
            
            if dropped_folder:
                self.folder_path = dropped_folder
                self.setText(f"已选择文件夹: {dropped_folder}")
                print(f"成功选择文件夹: {dropped_folder}")  # 调试信息
                event.setDropAction(Qt.CopyAction)
                event.accept()
            else:
                print("错误: 没有检测到文件夹 (可能是文件或无效路径)")  # 调试信息
                QMessageBox.warning(self, "警告", "请拖入文件夹,不是文件!")
                event.ignore()
        else:
            print("错误: 没有URLs")  # 调试信息
            event.ignore()


class MainWindow(QMainWindow):
    """主窗口类"""
    
    def __init__(self):
        super().__init__()
        self.file_data = []  # 存储文件信息的列表
        self.init_ui()
        
    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle("文件夹文件名提取工具")
        self.setGeometry(100, 100, 800, 600)
        
        # 创建中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 创建布局
        layout = QVBoxLayout(central_widget)
        
        # 标题标签
        title_label = QLabel("文件夹文件名提取工具\n快捷方式无效")
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setStyleSheet("font-size: 18px; font-weight: bold; margin: 10px;")
        layout.addWidget(title_label)
        
        # 拖拽区域
        self.file_list_widget = FileListWidget()
        self.file_list_widget.setMinimumHeight(200)
        self.file_list_widget.setStyleSheet("""
            QTextEdit {
                border: 2px dashed #aaa;
                border-radius: 10px;
                background-color: #f9f9f9;
                font-size: 14px;
                padding: 10px;
            }
        """)
        layout.addWidget(self.file_list_widget)
        
        # 按钮布局
        button_layout = QHBoxLayout()
        
        # 获取文件名按钮
        self.get_files_btn = QPushButton("获取文件名")
        self.get_files_btn.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 10px 20px;
                font-size: 14px;
                border-radius: 5px;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
        """)
        self.get_files_btn.clicked.connect(self.get_files)
        button_layout.addWidget(self.get_files_btn)
        
        # 导出Excel按钮
        self.export_btn = QPushButton("导出Excel")
        self.export_btn.setStyleSheet("""
            QPushButton {
                background-color: #2196F3;
                color: white;
                border: none;
                padding: 10px 20px;
                font-size: 14px;
                border-radius: 5px;
            }
            QPushButton:hover {
                background-color: #1976D2;
            }
        """)
        self.export_btn.clicked.connect(self.export_to_excel)
        self.export_btn.setEnabled(False)  # 初始状态禁用
        button_layout.addWidget(self.export_btn)
        
        layout.addLayout(button_layout)
        
        # 结果显示区域
        self.result_text = QTextEdit()
        self.result_text.setReadOnly(True)
        self.result_text.setPlaceholderText("文件列表将在这里显示...")
        layout.addWidget(self.result_text)
        
    def get_all_files(self, folder_path):
        """递归获取文件夹中的所有文件"""
        file_list = []
        
        try:
            for root, dirs, files in os.walk(folder_path):
                # 获取相对于根文件夹的路径
                relative_root = os.path.relpath(root, folder_path)
                if relative_root == '.':
                    relative_root = '根目录'
                
                # 添加文件信息
                for file in files:
                    file_list.append({
                        '目录': relative_root,
                        '文件名': file
                    })
                    
        except Exception as e:
            QMessageBox.critical(self, "错误", f"读取文件夹时出错: {str(e)}")
            return []
            
        return file_list
    
    def get_files(self):
        """获取文件名按钮点击事件"""
        if not self.file_list_widget.folder_path:
            QMessageBox.warning(self, "警告", "请先拖入一个文件夹!")
            return
            
        # 获取所有文件
        self.file_data = self.get_all_files(self.file_list_widget.folder_path)
        
        if not self.file_data:
            QMessageBox.information(self, "信息", "该文件夹中没有找到任何文件。")
            return
            
        # 显示结果
        result_text = f"共找到 {len(self.file_data)} 个文件:\n\n"
        
        # 按目录分组显示
        current_dir = None
        for item in self.file_data:
            if item['目录'] != current_dir:
                current_dir = item['目录']
                result_text += f"\n📁 {current_dir}:\n"
            result_text += f"  📄 {item['文件名']}\n"
            
        self.result_text.setText(result_text)
        self.export_btn.setEnabled(True)  # 启用导出按钮
        
    def export_to_excel(self):
        """导出到Excel文件"""
        if not self.file_data:
            QMessageBox.warning(self, "警告", "没有数据可以导出!")
            return
            
        # 选择保存位置
        file_path, _ = QFileDialog.getSaveFileName(
            self, 
            "保存Excel文件", 
            "文件列表.xlsx", 
            "Excel文件 (*.xlsx);;所有文件 (*)"
        )
        
        if not file_path:
            return
            
        try:
            # 创建DataFrame
            df = pd.DataFrame(self.file_data)
            
            # 导出到Excel
            df.to_excel(file_path, index=False, sheet_name='文件列表')
            
            QMessageBox.information(
                self, 
                "成功", 
                f"文件已成功导出到:\n{file_path}\n\n共导出 {len(self.file_data)} 个文件记录。"
            )
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"导出Excel时出错: {str(e)}")


def main():
    """主函数"""
    app = QApplication(sys.argv)
    
    # 设置应用程序样式
    app.setStyleSheet("""
        QMainWindow {
            background-color: #f0f0f0;
        }
        QLabel {
            color: #333;
        }
        QTextEdit {
            background-color: white;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-family: 'Microsoft YaHei', Arial, sans-serif;
        }
    """)
    
    window = MainWindow()
    window.show()
    
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

使用指南

安装依赖

pip install PyQt5 pandas openpyxl

运行应用

python main.py

操作步骤

  • 选择文件夹:将目标文件夹拖拽到应用的拖拽区域
  • 获取文件列表:点击"获取文件名"按钮开始扫描
  • 查看结果:在结果显示区域查看文件列表
  • 导出数据:点击"导出Excel"按钮保存结果

注意事项

  • 仅支持文件夹拖拽,不支持单个文件
  • 快捷方式无效,需要拖拽实际文件夹
  • 大型文件夹可能需要较长处理时间

技术亮点

1. 跨平台拖拽兼容性

通过实现dragMoveEvent方法,确保在Windows平台上的拖拽操作稳定性:

def dragMoveEvent(self, event):
    if event.mimeData().hasUrls():
        for url in event.mimeData().urls():
            if url.isLocalFile() and os.path.isdir(url.toLocalFile()):
                event.setDropAction(Qt.CopyAction)
                event.accept()
                return
    event.ignore()

2. 健壮的错误处理

  • 文件访问权限检查
  • 路径有效性验证
  • 用户友好的错误提示

3. 内存优化

  • 使用生成器模式处理大量文件
  • 及时释放不需要的数据结构
  • 避免重复加载文件信息

4. 调试支持

内置详细的调试日志输出,便于问题排查:

print(f"检测到URLs: {len(urls)}个")
print(f"检查路径: {file_path}")
print(f"成功选择文件夹: {dropped_folder}")

扩展功能建议

短期优化

  • 添加文件类型过滤功能
  • 支持多种导出格式(CSV、JSON)
  • 添加文件大小统计
  • 实现进度条显示

长期规划

  • 支持网络文件夹
  • 添加文件预览功能
  • 实现批量重命名
  • 集成云存储服务

项目结构

文件夹文件名提取工具/
├── main.py              # 主程序文件
├── requirements.txt     # 依赖包列表
├── README.md           # 项目说明
└── blog.md             # 技术博客(本文档)

总结

这个文件夹文件名提取工具展示了PyQt5在桌面应用开发中的强大能力。通过合理的架构设计、用户友好的界面和健壮的功能实现,为用户提供了一个实用的文件管理工具。

项目的技术特点包括:

  • 现代化的GUI设计:采用PyQt5构建响应式界面
  • 直观的交互方式:支持拖拽操作,降低使用门槛
  • 完整的数据处理流程:从文件扫描到Excel导出的完整链路
  • 跨平台兼容性:针对不同操作系统进行了优化

该项目不仅解决了实际的文件管理需求,也为PyQt5桌面应用开发提供了一个很好的参考案例。无论是对于学习GUI编程的开发者,还是需要文件管理工具的用户,都具有很好的参考价值。

以上就是python开发一个文件夹文件名提取工具(附完整代码)的详细内容,更多关于python文件名提取的资料请关注脚本之家其它相关文章!

相关文章

  • pycharm上的python虚拟环境移到离线机器上的方法步骤

    pycharm上的python虚拟环境移到离线机器上的方法步骤

    本人在工作中需要在离线Windows环境中使用,本文主要介绍了pycharm上的python虚拟环境移到离线机器上的方法步骤,具有一定的参考价值,感兴趣的可以了解一下
    2021-10-10
  • Python利用Faiss库实现ANN近邻搜索的方法详解

    Python利用Faiss库实现ANN近邻搜索的方法详解

    这篇文章主要介绍了Python利用Faiss库实现ANN近邻搜索的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-08-08
  • Python编程mac下使用pycharm小技巧

    Python编程mac下使用pycharm小技巧

    这篇文章主要介绍了Python编程中在mac下使用pycharm的一些小技巧,建议正在使用Pycharm的同学们可以收藏阅读,可以节省你的编程时间
    2021-09-09
  • Keras搭建自编码器操作

    Keras搭建自编码器操作

    这篇文章主要介绍了Keras搭建自编码器操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • Python使用python-can实现合并BLF文件

    Python使用python-can实现合并BLF文件

    python-can库是 Python 生态中专注于 CAN 总线通信与数据处理的强大工具,本文将使用python-can为 BLF 文件合并提供高效灵活的解决方案,有需要的小伙伴可以了解下
    2025-07-07
  • Python中使用pip换源的流程分析

    Python中使用pip换源的流程分析

    pip是一个用于安装、升级和管理Python库的工具,它允许你从Python包索引(PyPI)下载和安装第三方库,在Python开发过程中,我们经常需要安装各种第三方库,本文给大家分享Python中使用pip换源的详细指南,感兴趣的朋友一起看看吧
    2024-12-12
  • 举例讲解Python中is和id的用法

    举例讲解Python中is和id的用法

    这篇文章主要介绍了举例讲解Python中is和id的用法,是Python学习当中的基础知识,作者举例进行了简单说明,需要的朋友可以参考下
    2015-04-04
  • Python使用BeautifulSoup库解析网页

    Python使用BeautifulSoup库解析网页

    在Python的网络爬虫中,网页解析是一项重要的技术。而在众多的网页解析库中,BeautifulSoup库凭借其简单易用而广受欢迎,在本篇文章中,我们将学习BeautifulSoup库的基本用法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2023-08-08
  • Python中列表的基本操作汇总

    Python中列表的基本操作汇总

    这篇文章主要介绍了python中列表的一些基本操作,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-10-10
  • python中的十大%占位符对应的格式化的使用方法

    python中的十大%占位符对应的格式化的使用方法

    本文主要介绍了python中的十大%占位符对应的格式化的使用方法,它可以很好的帮助我们解决一些字符串格式化的问题, 文中通过示例代码介绍的非常详细,感兴趣的小伙伴们可以参考一下
    2022-01-01

最新评论