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文件名提取的资料请关注脚本之家其它相关文章!

相关文章

  • Python制作一个PPT文本提取工具

    Python制作一个PPT文本提取工具

    这篇文章主要为大家详细介绍了如何使用Python开发一个带图形界面的PPT文本提取工具,可以从PPTX文件中提取所有文本内容,有需要的小伙伴可以了解下
    2025-01-01
  • python中有帮助函数吗

    python中有帮助函数吗

    在本篇文章里小编给大家分享的是一篇关于python帮助函数详解内容,有兴趣的朋友们可以学习下。
    2020-06-06
  • 讲解Python中运算符使用时的优先级

    讲解Python中运算符使用时的优先级

    这篇文章主要介绍了讲解Python中运算符使用时的优先级,是Python学习当中的基础知识,需要的朋友可以参考下
    2015-05-05
  • python编程webpy框架模板之def with学习

    python编程webpy框架模板之def with学习

    这篇文章主要为大家介绍了python编程web.py框架模板之def with的学习有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • Python计算序列相似度的算法实例

    Python计算序列相似度的算法实例

    这篇文章主要介绍了Python计算序列相似度的算法实例,求两个序列转换的最少交换步骤和最小交换距离,本文提供了部分实现代码与解决思路,对开发非常有帮助,需要的朋友可以参考下
    2023-07-07
  • python使用opencv按一定间隔截取视频帧

    python使用opencv按一定间隔截取视频帧

    这篇文章主要为大家详细介绍了python使用opencv按一定间隔截取视频帧,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Windows和Linux下Python输出彩色文字的方法教程

    Windows和Linux下Python输出彩色文字的方法教程

    这篇文章主要介绍了在Windows和Linux中Python输出彩色文字的方法,通过设置彩色文字给大家更醒目的效果,文中给出了详细的介绍和示例代码,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-05-05
  • 如何基于Python制作有道翻译小工具

    如何基于Python制作有道翻译小工具

    这篇文章主要介绍了如何基于Python制作有道翻译小工具,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 手把手教你如何使python变为可执行文件

    手把手教你如何使python变为可执行文件

    对于exe可执行文件,相信大家都不陌生,下面这篇文章主要给大家介绍了关于如何使python变为可执行文件的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • Jupyter Lab设置切换虚拟环境的实现步骤

    Jupyter Lab设置切换虚拟环境的实现步骤

    本文主要介绍了Jupyter Lab设置切换虚拟环境的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02

最新评论