python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > python文件名提取

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

作者:小庄-Python办公

这篇文章主要为大家详细介绍了如何使用python开发一个文件夹文件名提取工具,专门用于提取文件夹中所有文件的名称并导出为Excel格式,感兴趣的小伙伴可以了解下

项目简介

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

主要功能特性

核心功能

用户体验

技术架构

技术栈

核心组件

1. FileListWidget 类

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

主要职责:

关键特性:

2. MainWindow 类

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

主要职责:

详细功能说明

拖拽功能实现

拖拽事件处理流程

关键代码解析

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]          │
├─────────────────────────────────────┤
│                                     │
│         结果显示区域                  │
│                                     │
└─────────────────────────────────────┘

样式设计

配色方案

交互反馈

效果图

完整代码

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

操作步骤

注意事项

技术亮点

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}")

扩展功能建议

短期优化

长期规划

项目结构

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

总结

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

项目的技术特点包括:

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

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

您可能感兴趣的文章:
阅读全文