使用Python创建多功能文件管理器

news2024/10/1 19:33:17
简介

在本文中,我们将探索一个使用Python的wxPython库开发的文件管理器应用程序。这个应用程序不仅能够浏览和选择文件,还支持文件预览、压缩、图片转换以及生成PPT演示文稿的功能。
C:\pythoncode\new\filemanager.py

完整代码

import wx
import os
import zipfile
from PIL import ImageGrab, Image
from pptx import Presentation
import win32com.client

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title="文件管理器", size=(800, 600))
        self.panel = wx.Panel(self)
        
        # 布局
        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
        self.top_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.mid_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.listbox_sizer = wx.BoxSizer(wx.VERTICAL)
        self.preview_sizer = wx.BoxSizer(wx.VERTICAL)
        self.bottom_sizer = wx.BoxSizer(wx.HORIZONTAL)

        # 文件类型选择
        self.file_type_choice = wx.Choice(self.panel, choices=["照片", "Word", "Excel", "PPT", "PDF"])
        self.file_type_choice.Bind(wx.EVT_CHOICE, self.on_file_type_selected)
        self.top_sizer.Add(self.file_type_choice, 1, wx.EXPAND | wx.ALL, 5)

        # 文件选择
        self.dir_picker = wx.DirPickerCtrl(self.panel, message="选择文件夹")
        self.dir_picker.Bind(wx.EVT_DIRPICKER_CHANGED, self.on_dir_picked)
        self.top_sizer.Add(self.dir_picker, 1, wx.EXPAND | wx.ALL, 5)

        # 包含子文件夹复选框
        self.include_subfolders_checkbox = wx.CheckBox(self.panel, label="包含子文件夹")
        self.include_subfolders_checkbox.Bind(wx.EVT_CHECKBOX, self.on_include_subfolders_checked)
        self.top_sizer.Add(self.include_subfolders_checkbox, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        # 分割器
        self.splitter = wx.SplitterWindow(self.panel)
        self.splitter.Bind(wx.EVT_SPLITTER_DCLICK, self.on_splitter_dclick)
        self.left_panel = wx.Panel(self.splitter)
        self.right_panel = wx.Panel(self.splitter)

        # 文件列表
        self.file_listbox = wx.ListBox(self.left_panel, style=wx.LB_MULTIPLE, size=(400, -1))
        self.file_listbox.Bind(wx.EVT_LISTBOX, self.on_file_selected)
        self.file_listbox.Bind(wx.EVT_LISTBOX_DCLICK, self.on_file_deselected)
        self.file_listbox.Bind(wx.EVT_LISTBOX, self.on_drag_select)        
        self.listbox_sizer.Add(self.file_listbox, 1, wx.EXPAND | wx.ALL, 5)
        
        # 全选和全不选按钮
        self.select_all_button = wx.Button(self.left_panel, label="全选")
        self.select_all_button.Bind(wx.EVT_BUTTON, self.on_select_all)
        self.deselect_all_button = wx.Button(self.left_panel, label="全不选")
        self.deselect_all_button.Bind(wx.EVT_BUTTON, self.on_deselect_all)
        self.listbox_sizer.Add(self.select_all_button, 0, wx.EXPAND | wx.ALL, 5)
        self.listbox_sizer.Add(self.deselect_all_button, 0, wx.EXPAND | wx.ALL, 5)

        # 设置左侧面板布局
        self.left_panel.SetSizer(self.listbox_sizer)

        # 预览窗口
        self.preview_panel = wx.Panel(self.right_panel, size=(400, 400))
        self.preview_sizer = wx.BoxSizer(wx.VERTICAL)
        self.preview_panel.SetSizer(self.preview_sizer)

        # self.preview_panel = wx.Panel(self.right_panel, size=(400, 400))
        # self.preview_panel.SetSizer(self.preview_sizer)
        # self.right_panel.SetSizer(self.preview_sizer)
        

        # 设置分割器布局
        self.splitter.SplitVertically(self.left_panel, self.right_panel)
        self.splitter.SetSashGravity(0.5)
        self.splitter.SetMinimumPaneSize(100)

        self.mid_sizer.Add(self.splitter, 1, wx.EXPAND | wx.ALL, 5)

        # 操作按钮
        self.zip_button = wx.Button(self.panel, label="压缩")
        self.zip_button.Bind(wx.EVT_BUTTON, self.on_zip)
        self.convert_button = wx.Button(self.panel, label="转换图片")
        self.convert_button.Bind(wx.EVT_BUTTON, self.on_convert)
        self.generate_ppt_button = wx.Button(self.panel, label="生成PPT文档")
        self.generate_ppt_button.Bind(wx.EVT_BUTTON, self.on_generate_ppt)

        self.bottom_sizer.Add(self.zip_button, 1, wx.EXPAND | wx.ALL, 5)
        self.bottom_sizer.Add(self.convert_button, 1, wx.EXPAND | wx.ALL, 5)
        self.bottom_sizer.Add(self.generate_ppt_button, 1, wx.EXPAND | wx.ALL, 5)

        # 整体布局
        self.main_sizer.Add(self.top_sizer, 0, wx.EXPAND)
        self.main_sizer.Add(self.mid_sizer, 1, wx.EXPAND)
        self.main_sizer.Add(self.bottom_sizer, 0, wx.EXPAND)
        
        self.panel.SetSizer(self.main_sizer)
        self.Show()

    def on_dir_picked(self, event):
        self.dir_path = self.dir_picker.GetPath()
        self.update_file_list()

    def on_file_type_selected(self, event):
        self.file_type = self.file_type_choice.GetStringSelection()
        self.update_file_list()

    def on_include_subfolders_checked(self, event):
        self.update_file_list()

    def update_file_list(self):
        if hasattr(self, 'dir_path') and hasattr(self, 'file_type'):
            self.file_listbox.Clear()
            include_subfolders = self.include_subfolders_checkbox.GetValue()
            for root, dirs, files in os.walk(self.dir_path):
                if not include_subfolders and root != self.dir_path:
                    continue
                for file in files:
                    if self.file_type == "照片" and file.lower().endswith(('png', 'jpg', 'jpeg')):
                        self.file_listbox.Append(os.path.join(root, file))
                    elif self.file_type == "Word" and file.lower().endswith('docx'):
                        self.file_listbox.Append(os.path.join(root, file))
                    elif self.file_type == "Excel" and file.lower().endswith('xlsx'):
                        self.file_listbox.Append(os.path.join(root, file))
                    elif self.file_type == "PPT" and file.lower().endswith('pptx'):
                        self.file_listbox.Append(os.path.join(root, file))
                    elif self.file_type == "PDF" and file.lower().endswith('pdf'):
                        self.file_listbox.Append(os.path.join(root, file))

    def on_file_selected(self, event):
        selections = self.file_listbox.GetSelections()
        if selections:
            file_path = self.file_listbox.GetString(selections[0])
            self.preview_file(file_path)
    
    def on_file_deselected(self, event):
        # 单击文件名时,取消选择
        event.Skip()

    def on_drag_select(self, event):
        selections = self.file_listbox.GetSelections()
        if selections:
            file_path = self.file_listbox.GetString(selections[0])
            self.preview_file(file_path)

    def on_select_all(self, event):
        count = self.file_listbox.GetCount()
        for i in range(count):
            self.file_listbox.Select(i)

    def on_deselect_all(self, event):
        count = self.file_listbox.GetCount()
        for i in range(count):
            self.file_listbox.Deselect(i)

    def preview_file(self, file_path):
        # Clear any existing content in the preview panel
        for child in self.preview_panel.GetChildren():
            child.Destroy()
        
        if file_path.lower().endswith(('png', 'jpg', 'jpeg')):
            try:
                original_image = wx.Image(file_path, wx.BITMAP_TYPE_ANY)
                # Get the size of the preview panel
                panel_size = self.preview_panel.GetSize()
                # Calculate the scaling factor to fit the image within the panel
                width_ratio = panel_size.width / original_image.GetWidth()
                height_ratio = panel_size.height / original_image.GetHeight()
                scale_factor = min(width_ratio, height_ratio)
                # Scale the image
                new_width = int(original_image.GetWidth() * scale_factor)
                new_height = int(original_image.GetHeight() * scale_factor)
                image = original_image.Scale(new_width, new_height, wx.IMAGE_QUALITY_HIGH)
                bitmap = wx.Bitmap(image)
                static_bitmap = wx.StaticBitmap(self.preview_panel, -1, bitmap)
                self.preview_sizer.Add(static_bitmap, 0, wx.CENTER)
            except Exception as e:
                print(f"Error loading image: {e}")
        # Other file types preview implementation can be added here
        self.preview_panel.Layout()
        self.right_panel.Layout()
    def on_zip(self, event):
        file_paths = [self.file_listbox.GetString(i) for i in self.file_listbox.GetSelections()]
        with zipfile.ZipFile(os.path.join(self.dir_path, 'compressed_files.zip'), 'w') as zipf:
            for file_path in file_paths:
                zipf.write(file_path, os.path.basename(file_path))

    def on_convert(self, event):
        file_paths = [self.file_listbox.GetString(i) for i in self.file_listbox.GetSelections()]
        self.process_files(file_paths)

    def process_files(self, file_paths):
        excel = win32com.client.Dispatch("Excel.Application")
        excel.Visible = False
        
        for file_path in file_paths:
            try:
                workbook = excel.Workbooks.Open(file_path)
                sheet = workbook.Sheets(1)
                
                # 获取工作表的使用范围
                used_range = sheet.UsedRange
                
                # 设置截图区域
                sheet.Range(used_range.Address).CopyPicture(Format=2)  # 2 表示位图
                
                # 创建一个临时图片对象并粘贴截图
                img = ImageGrab.grabclipboard()
                
                if img:
                    # 保存截图
                    base_name = os.path.splitext(file_path)[0]
                    img_path = f"{base_name}_screenshot.png"
                    img.save(img_path)
                    print(f"截图已保存: {img_path}")
                else:
                    print(f"无法为 {file_path} 创建截图")
                
                workbook.Close(SaveChanges=False)
            except Exception as e:
                print(f"处理 {file_path} 时出错: {str(e)}")
        
        excel.Quit()
        wx.MessageBox("所有文件处理完成", "完成", wx.OK | wx.ICON_INFORMATION)

    def on_generate_ppt(self, event):
        file_paths = [self.file_listbox.GetString(i) for i in self.file_listbox.GetSelections()]
        prs = Presentation()
        for file_path in file_paths:
            if file_path.lower().endswith(('png', 'jpg', 'jpeg')):
                slide = prs.slides.add_slide(prs.slide_layouts[5])
                img_path = file_path
                slide.shapes.add_picture(img_path, 0, 0, prs.slide_width, prs.slide_height)
        prs.save(os.path.join(self.dir_path, 'output_ppt.pptx'))

    def on_splitter_dclick(self, event):
        self.splitter.Unsplit()
    def on_drag_select(self, event):
        selections = self.file_listbox.GetSelections()
        if selections:
            file_path = self.file_listbox.GetString(selections[0])
            self.preview_file(file_path)

if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

环境准备

在开始之前,请确保你的Python环境中已经安装了以下库:

  • wxPython:用于创建GUI应用程序。
  • Pillow:用于图像处理。
  • python-pptx:用于操作PPT文件。
  • win32com.client:用于处理Excel文件(仅限Windows系统)。

可以通过以下命令安装所需的库:

pip install wxPython Pillow python-pptx pywin32
应用程序结构

我们的文件管理器基于wxPython的框架构建,主要分为以下几个部分:

  1. 主窗口 (MyFrame 类):包含整个应用程序的布局和控件。
  2. 文件类型选择:允许用户根据文件类型筛选文件。
  3. 文件选择:使用目录选择控件让用户选择要浏览的文件夹。
  4. 子文件夹选项:一个复选框,决定是否包括子文件夹中的文件。
  5. 文件列表和预览:展示选中文件夹中的文件,并提供预览功能。
  6. 操作按钮:包括压缩文件、转换图片和生成PPT文档的功能。
代码解析
初始化和布局设置
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title="文件管理器", size=(800, 600))
        # 初始化窗口、面板、大小器等
        # ...
文件类型选择和目录选择
self.file_type_choice = wx.Choice(self.panel, choices=["照片", "Word", "Excel", "PPT", "PDF"])
self.dir_picker = wx.DirPickerCtrl(self.panel, message="选择文件夹")

这里创建了一个下拉菜单供用户选择文件类型,以及一个目录选择控件来选择文件所在的文件夹。

文件列表更新
def update_file_list(self):
    # 根据选择的目录和文件类型更新文件列表
    # ...
文件预览
def preview_file(self, file_path):
    # 根据文件类型显示预览
    # ...
压缩文件
def on_zip(self, event):
    # 将选中的文件压缩成一个ZIP文件
    # ...
转换图片
def on_convert(self, event):
    # 将Excel文件转换为图片
    # ...
生成PPT文档
def on_generate_ppt(self, event):
    # 使用选中的图片生成PPT文档
    # ...
总结

这个文件管理器应用程序是一个功能丰富的工具,它展示了wxPython在创建桌面应用程序方面的强大能力。通过结合其他库,我们能够扩展其功能,满足不同的需求。

结果如下

在这里插入图片描述

结尾

希望本文能够帮助你了解如何使用Python和wxPython创建具有多种文件操作功能的桌面应用程序。如果你有任何问题或建议,请在下方留言。

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

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

相关文章

ChatGLM3Loader发生错误Library cudart is not initialized

ChatGLM3Loader执行时发生错误: Library cudart is not initialized。 文章《Chatglm3部署踩坑记录》里提到是因为没有安装 CUDA Toolkit 引起。 1、用 nvidia-smi.exe 命令查看显卡当前驱动程序版本 2、NVIDIA CUDA 工具包发行说明,每个 CUDA 工具包版…

深度学习中常用的激活函数和损失函数

ReLu和Sigmoid的区别。 ReLU在正数区域提供线性响应,有助于加速训练并减少梯度消失问题,而Sigmoid在所有区域都是非线性的,输出范围是0到1,适用于二分类问题,但在深网络中容易造成梯度消失。 Softmax函数的作用。 Soft…

《Advanced RAG》-03-使用 RAGAs + LlamaIndex 进行 RAG 评估

摘要 文章首先介绍了 RAG 评估的三个主要部分:输入查询、检索上下文和 LLM 生成的响应。 提到了 RAGAs 提出的 RAG 评估指标,包括 Faithfulness、Answer Relevance 和 Context Relevance,以及 RAGAs 网站提供的两个额外指标:Conte…

Jenkins未授权访问漏洞 *

漏洞复现 步骤一:使用以下fofa语法进行产品搜索.... port"8080" && app"JENKINS" && title"Dashboard [Jenkins]" 步骤二:在打开的URL中...点击Manage Jenkins --> Scritp Console在执行以下命令..…

JS使用 navigator.clipboard 操作剪切板

注意:需要在安全域下才能够使用,比如:https 协议的地址、127.0.0.1、localhost safari浏览器需要打开配置,在地址栏输入 about:config,搜索 clipboard,将 asyncClipboard 由 false 改为 true,然…

8.3,8.4总结

1.改进渲染 // 加载头像图像InputStream inputStream new ByteArrayInputStream(message.getFileBytes());Image image new Image(inputStream); // 第二个参数表示是否缓存图片,根据需要设置imageView.setImage(image);// 设置头像视图大小imageView.setFitWidth…

安装eclipse时候 打开eclipse出现一连串英文

问题描述:打开eclipse失败,提示错误Version 1.8.xx of the JVM is not suitable for this product Version:11 or greater is required 本地已经有1.8.XX 的jdk,但因为新安装的eclipse需要JVM更高的版本。 原因:jdk版本太低 解…

基于随机森林、XGBoost、lightGBM的大气污染预测可视化系统【前后端交互】

文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主数据介绍系统界面展示系统登陆展示系统主界面可视化展示机器学习模型预测展示框架界面功能每文一语 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 数据介绍…

【C语言】C语言期末突击/考研--结构体与C++引用

一、结构体--结构体对齐--结构体数组 1.1.结构体的定义、初始化、结构体数组 有时候需要将不同类型的数据组合为一一个整体,以便于引用。 例如,一名学生有学号、姓 名、性别、年龄、地址等属性,如果针对学生的学号、姓名、年龄等都单独定义一…

代码坏味道有24种?我看未必

微信公众号:牛奶 Yoka 的小屋 有任何问题。欢迎来撩~ 最近更新:2024/08/03 [大家好,我是牛奶。] 我在上一篇文章打开IDEA,程序员思考的永远只有两件事!中,通过代码命名、重复代码、合格方法三个章节&#…

PXE实验

实验前准备 关闭VMware的dhcp 点击 编辑 点击 虚拟网络编辑器 选择 NAT模式 将dhcp取消勾选 准备两台虚拟机 一台试验机,(网络环境正常并且有图形化的界面的rhel7) 一台测试机 init 5 --------------> 开启图形化界面 如…

《C/C++实战进阶》介绍

🚀 前言 本文是《C/C实战进阶》专栏的说明贴(点击链接,跳转到专栏主页,欢迎订阅,持续更新…)。 专栏介绍:以多年的开发实战为基础,总结并讲解一些的C/C基础与项目实战进阶内容&…

AI用Alice_split_toolset切割音频的采样率

AI用Alice_split_toolset切割音频的采样率 目录 AI用Alice_split_toolset切割音频的采样率 一、Sample rate采样率的概念 二、Alice_split_toolset切割音频的参数 2.1、字符串参数--input_folder输入文件夹路径 2.2、字符串参数--output_folder输出文件夹路径 2.3、字符串…

第一次作业,sql注入总结

sqli-labs靶场中演示: less1: 注入点为: $sql"SELECT * FROM users WHERE id$id LIMIT 0,1"; get输入一个id,可以逃逸出单引号来实现sql注入。 正常的输入为,输出数据库中查询的内容。 http://127.0.0…

如何将PyCharm 中使用 PDM 管理的 Django 项目迁移到 VS Code 并确保一切正常工作?

嗨,我是兰若姐姐,相信很多小伙伴都遇到过这种情况,使用pycharm用习惯了,想换个编辑器,比如换成vscode,今天就告诉大家,如果轻松切换到vscode 步骤 1:在 VS Code 中打开项目 打开 V…

并行状态的广播事件

平行状态的广播事件 此示例显示了并行状态下事件广播操作的行为。 最初,图表处于休眠状态。并行子状态A.A1.A1a和A.A2.A2a处于活动状态。事件E_one发生并唤醒图表,图表从根向下通过层次结构处理事件: 1 图表根会检查根级别是否存在E_one导致…

Docker简介 MacM1安装Docker

文章目录 1 Docker简介2 Docker VS 虚拟机1 Docker优势2 Docker用途 3 MacM1 下载安装Docker1 配置环境变量 4 配置Docker2 设置Docker资源3 设置Docker镜像 参考 1 Docker简介 Docker主要解决了软件开发和运行配置的问题,但是由于其功能的强大,也被应用…

跨境电商下载工具天猫主图sku图等图片信息

优美的图片是电商卖家吸引顾客、展示商品魅力的关键。高质量的图片能够提升产品吸引力,增强用户信任感,促进购买决策,从而直接影响销量和店铺形象。在视觉营销的时代,优秀的商品图片更是流量转化的利器。 使用图快下载器&#xf…

多租户系统数据隔离方案

目录 前言 数据行 数据表 基于业务场景 基于数据量 数据库 数据源表 动态数据源 前言 多租户系统是一种将多个客户的数据和应用程序分开的系统,每个客户被视为一个独立的租户,互不干扰。实现多租户系统的关键之一是确保数据的隔离。 数据隔离的…

Windows 添加自定义服务实现开机(用户登录之前)自动运行 Python 脚本

实现效果 使用 Python 编写的一个脚本, 希望在 Windows 系统启动时, 用户登录之前就自动运行. 准备工作 首先确保 Python 脚本可以手动正常运行, 演示起见, 编写下面的一个简单的脚本用于在 C 盘根目录中生成一个包含脚本运行时间戳的文本文件. Python 脚本存放在 C:\Python…