Python文件管理器:一个基于wxPython的桌面应用

在当今的软件开发世界中,管理大量的源代码文件变得越来越重要。无论是个人项目还是大型团队协作,有一个强大而灵活的文件管理工具都可以大大提高工作效率。今天,我们要介绍一个基于Python和wxPython构建的文件管理器,它专门用于管理.py文件。

C:\pythoncode\new\managefiles.py

全部代码

python 复制代码
import wx
import wx.lib.mixins.listctrl as listmix
import sqlite3
import os
import subprocess
from datetime import datetime
import openpyxl

class EditableListCtrl(wx.ListCtrl, listmix.TextEditMixin):
    def __init__(self, parent, style):
        wx.ListCtrl.__init__(self, parent, style=style)
        listmix.TextEditMixin.__init__(self)

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title="Manage .py Files", size=(1000, 600))
        panel = wx.Panel(self)

        vbox = wx.BoxSizer(wx.VERTICAL)

        # Folder selection and scan button
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        self.folder_picker = wx.DirPickerCtrl(panel)
        scan_btn = wx.Button(panel, label="Scan")
        scan_btn.Bind(wx.EVT_BUTTON, self.on_scan)
        hbox1.Add(self.folder_picker, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
        hbox1.Add(scan_btn, flag=wx.ALL, border=5)

        # ListView1 for displaying .py files
        self.listview1 = wx.ListCtrl(panel, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
        self.listview1.InsertColumn(0, "File Name", width=200)
        self.listview1.InsertColumn(1, "Full Path", width=400)
        self.listview1.InsertColumn(2, "Date Modified", width=200)
        self.listview1.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_listview1_double_click)

        # Search box for ListView1
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        self.search1 = wx.TextCtrl(panel)
        search1_btn = wx.Button(panel, label="Search ListView1")
        search1_btn.Bind(wx.EVT_BUTTON, self.on_search1)
        hbox2.Add(self.search1, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
        hbox2.Add(search1_btn, flag=wx.ALL, border=5)

        # ListView2 for selected files with editable remarks and valid checkbox
        self.listview2 = wx.ListCtrl(panel, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
        self.listview2.InsertColumn(0, "File Name", width=200)
        self.listview2.InsertColumn(1, "Full Path", width=400)
        self.listview2.InsertColumn(2, "Date Modified", width=200)
        self.listview2.InsertColumn(3, "Remarks", width=150)
        self.listview2.InsertColumn(4, "Valid", width=50)
        self.listview2.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_listview2_double_click)

        # Search box for ListView2
        hbox3 = wx.BoxSizer(wx.HORIZONTAL)
        self.search2 = wx.TextCtrl(panel)
        search2_btn = wx.Button(panel, label="Search ListView2")
        search2_btn.Bind(wx.EVT_BUTTON, self.on_search2)
        hbox3.Add(self.search2, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
        hbox3.Add(search2_btn, flag=wx.ALL, border=5)

        # Buttons for opening, saving, and deleting
        hbox4 = wx.BoxSizer(wx.HORIZONTAL)
        open_btn = wx.Button(panel, label="Open in VSCode")
        open_btn.Bind(wx.EVT_BUTTON, self.on_open)
        save_btn = wx.Button(panel, label="Save to Database")
        save_btn.Bind(wx.EVT_BUTTON, self.save_to_database)
        delete_btn = wx.Button(panel, label="Delete Selected")
        delete_btn.Bind(wx.EVT_BUTTON, self.on_delete)
        hbox4.Add(open_btn, flag=wx.ALL, border=5)
        hbox4.Add(save_btn, flag=wx.ALL, border=5)
        hbox4.Add(delete_btn, flag=wx.ALL, border=5)

        # ListView3 for displaying database records
        self.listview3 = wx.ListCtrl(panel, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
        self.listview3.InsertColumn(0, "File Name", width=200)
        self.listview3.InsertColumn(1, "Full Path", width=400)
        self.listview3.InsertColumn(2, "Date Modified", width=200)
        self.listview3.InsertColumn(3, "Remarks", width=150)
        self.listview3.InsertColumn(4, "Valid", width=50)

        # Buttons for refreshing and deleting database records, opening in VSCode, and exporting to Excel
        hbox5 = wx.BoxSizer(wx.HORIZONTAL)
        refresh_btn = wx.Button(panel, label="Refresh Database Records")
        refresh_btn.Bind(wx.EVT_BUTTON, self.on_refresh)
        delete_db_btn = wx.Button(panel, label="Delete Database Record")
        delete_db_btn.Bind(wx.EVT_BUTTON, self.on_delete_db)
        open_vscode_btn = wx.Button(panel, label="Open in VSCode")
        open_vscode_btn.Bind(wx.EVT_BUTTON, self.on_open_vscode)
        export_excel_btn = wx.Button(panel, label="Export to Excel")
        export_excel_btn.Bind(wx.EVT_BUTTON, self.on_export_excel)
        hbox5.Add(refresh_btn, flag=wx.ALL, border=5)
        hbox5.Add(delete_db_btn, flag=wx.ALL, border=5)
        hbox5.Add(open_vscode_btn, flag=wx.ALL, border=5)
        hbox5.Add(export_excel_btn, flag=wx.ALL, border=5)

        # Adding all to the main vertical box
        vbox.Add(hbox1, flag=wx.EXPAND | wx.ALL, border=5)
        vbox.Add(self.listview1, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
        vbox.Add(hbox2, flag=wx.EXPAND | wx.ALL, border=5)
        vbox.Add(self.listview2, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
        vbox.Add(hbox3, flag=wx.EXPAND | wx.ALL, border=5)
        vbox.Add(hbox4, flag=wx.ALIGN_CENTER | wx.ALL, border=5)
        vbox.Add(self.listview3, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
        vbox.Add(hbox5, flag=wx.ALIGN_CENTER | wx.ALL, border=5)

        panel.SetSizer(vbox)

        self.db_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "files1.db")

    def on_scan(self, event):
        folder_path = self.folder_picker.GetPath()
        if not folder_path:
            wx.MessageBox("Please select a folder.", "Error", wx.OK | wx.ICON_ERROR)
            return

        self.listview1.DeleteAllItems()

        py_files = []
        for root, dirs, files in os.walk(folder_path):
            for file in files:
                if file.endswith(".py"):
                    full_path = os.path.join(root, file)
                    date_modified = os.path.getmtime(full_path)
                    date_str = wx.DateTime.FromTimeT(int(date_modified)).FormatISOCombined()
                    py_files.append((file, full_path, date_str, date_modified))

        # Sort files by date modified (most recent first)
        py_files.sort(key=lambda x: x[3], reverse=True)

        for file, full_path, date_str, _ in py_files:
            index = self.listview1.InsertItem(self.listview1.GetItemCount(), file)
            self.listview1.SetItem(index, 1, full_path)
            self.listview1.SetItem(index, 2, date_str)

    def on_listview1_double_click(self, event):
        selected = self.listview1.GetFirstSelected()
        if selected == -1:
            return

        file_name = self.listview1.GetItemText(selected)
        full_path = self.listview1.GetItem(selected, 1).GetText()
        date_modified = self.listview1.GetItem(selected, 2).GetText()

        new_index = self.listview2.InsertItem(self.listview2.GetItemCount(), file_name)
        self.listview2.SetItem(new_index, 1, full_path)
        self.listview2.SetItem(new_index, 2, date_modified)
        self.listview2.SetItem(new_index, 3, "")
        self.listview2.SetItem(new_index, 4, "No")

    def on_listview2_double_click(self, event):
        selected = self.listview2.GetFirstSelected()
        if selected == -1:
            return

        remarks = self.listview2.GetItem(selected, 3).GetText()
        valid = self.listview2.GetItem(selected, 4).GetText()

        dlg = EditDialog(self, remarks, valid == "Yes")
        if dlg.ShowModal() == wx.ID_OK:
            new_remarks, new_valid = dlg.get_values()
            self.listview2.SetItem(selected, 3, new_remarks)
            self.listview2.SetItem(selected, 4, new_valid)
        
        dlg.Destroy()

    def on_search1(self, event):
        search_term = self.search1.GetValue().lower()
        self.search_in_listview(self.listview1, search_term)

    def on_search2(self, event):
        search_term = self.search2.GetValue().lower()
        self.search_in_listview(self.listview2, search_term)

    # def search_in_listview(self, listview, search_term):
    #     listview.DeleteAllItems()
    #     for index in range(listview.GetItemCount()):
    #         item_text = listview.GetItemText(index).lower()
    #         full_path = listview.GetItem(index, 1).GetText().lower()
    #         if search_term in item_text or search_term in full_path:
    #             new_index = listview.InsertItem(listview.GetItemCount(), listview.GetItemText(index))
    #             for col in range(1, listview.GetColumnCount()):
    #                 listview.SetItem(new_index, col, listview.GetItem(index, col).GetText())
    def search_in_listview(self, listview, search_term):
        for i in range(listview.GetItemCount()):
            item = listview.GetItem(i)
            if search_term in item.GetText().lower() or search_term in listview.GetItem(i, 1).GetText().lower():
                item.SetBackgroundColour(wx.YELLOW)
                listview.SetItem(item)
                listview.EnsureVisible(i)
            else:
                item.SetBackgroundColour(wx.WHITE)
                listview.SetItem(item)

        if not search_term:
            for i in range(listview.GetItemCount()):
                item = listview.GetItem(i)
                item.SetBackgroundColour(wx.WHITE)
                listview.SetItem(item)

    def on_open(self, event):
        self.open_in_vscode(self.listview2)

    def on_open_vscode(self, event):
        self.open_in_vscode(self.listview3)

    def open_in_vscode(self, listview):
        selected = listview.GetFirstSelected()
        if selected == -1:
            wx.MessageBox("Please select a file to open", "Error", wx.OK | wx.ICON_ERROR)
            return

        full_path = listview.GetItem(selected, 1).GetText()
        subprocess.Popen(["C:\\Users\\86182\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe", full_path])

    # def save_to_database(self, event):
    #     try:
    #         conn = sqlite3.connect(self.db_path)
    #         cursor = conn.cursor()

    #         # Ensure table exists
    #         cursor.execute('''CREATE TABLE IF NOT EXISTS files (
    #                             id INTEGER PRIMARY KEY AUTOINCREMENT,
    #                             file_name TEXT,
    #                             full_path TEXT,
    #                             date_modified TEXT,
    #                             remarks TEXT,
    #                             valid INTEGER)''')

    #         cursor.execute('DELETE FROM files')  # Clear old records

    #         for index in range(self.listview2.GetItemCount()):
    #             file_name = self.listview2.GetItemText(index)
    #             full_path = self.listview2.GetItem(index, 1).GetText()
    #             date_modified = self.listview2.GetItem(index, 2).GetText()
    #             remarks = self.listview2.GetItem(index, 3).GetText()
    #             valid = self.listview2.GetItem(index, 4).GetText()
    #             valid = 1 if valid == "Yes" else 0

    #             cursor.execute('INSERT INTO files (file_name, full_path, date_modified, remarks, valid) VALUES (?, ?, ?, ?, ?)',
    #                         (file_name, full_path, date_modified, remarks, valid))

    #         conn.commit()  # Save changes
    #     except sqlite3.Error as e:
    #         wx.MessageBox(f"Database error: {e}", "Error", wx.OK | wx.ICON_ERROR)
    #     finally:
    #         conn.close()  # Ensure connection is closed

    #     wx.MessageBox("Data saved to the database.", "Info", wx.OK | wx.ICON_INFORMATION)
    def save_to_database(self, event):
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()

            # Ensure table exists
            cursor.execute('''CREATE TABLE IF NOT EXISTS files (
                                id INTEGER PRIMARY KEY AUTOINCREMENT,
                                file_name TEXT,
                                full_path TEXT,
                                date_modified TEXT,
                                remarks TEXT,
                                valid INTEGER)''')

            # Append new records instead of deleting old ones
            for index in range(self.listview2.GetItemCount()):
                file_name = self.listview2.GetItemText(index)
                full_path = self.listview2.GetItem(index, 1).GetText()
                date_modified = self.listview2.GetItem(index, 2).GetText()
                remarks = self.listview2.GetItem(index, 3).GetText()
                valid = self.listview2.GetItem(index, 4).GetText()
                valid = 1 if valid == "Yes" else 0

                # Check if the record already exists
                cursor.execute('SELECT * FROM files WHERE full_path = ?', (full_path,))
                if cursor.fetchone() is None:
                    # If it doesn't exist, insert a new record
                    cursor.execute('INSERT INTO files (file_name, full_path, date_modified, remarks, valid) VALUES (?, ?, ?, ?, ?)',
                                (file_name, full_path, date_modified, remarks, valid))
                else:
                    # If it exists, update the existing record
                    cursor.execute('UPDATE files SET file_name = ?, date_modified = ?, remarks = ?, valid = ? WHERE full_path = ?',
                                (file_name, date_modified, remarks, valid, full_path))

            conn.commit()  # Save changes
        except sqlite3.Error as e:
            wx.MessageBox(f"Database error: {e}", "Error", wx.OK | wx.ICON_ERROR)
        finally:
            conn.close()  # Ensure connection is closed

        wx.MessageBox("Data saved to the database.", "Info", wx.OK | wx.ICON_INFORMATION)

    def on_delete(self, event):
        selected = self.listview2.GetFirstSelected()
        if selected == -1:
            wx.MessageBox("Please select a file to delete", "Error", wx.OK | wx.ICON_ERROR)
            return

        self.listview2.DeleteItem(selected)

    def on_refresh(self, event):
        self.listview3.DeleteAllItems()

        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute('SELECT file_name, full_path, date_modified, remarks, valid FROM files')

        for row in cursor.fetchall():
            file_name, full_path, date_modified, remarks, valid = row
            valid_text = "Yes" if valid == 1 else "No"

            index = self.listview3.InsertItem(self.listview3.GetItemCount(), file_name)
            self.listview3.SetItem(index, 1, full_path)
            self.listview3.SetItem(index, 2, date_modified)
            self.listview3.SetItem(index, 3, remarks)
            self.listview3.SetItem(index, 4, valid_text)

        conn.close()

    def on_delete_db(self, event):
        selected = self.listview3.GetFirstSelected()
        if selected == -1:
            wx.MessageBox("Please select a database record to delete", "Error", wx.OK | wx.ICON_ERROR)
            return

        full_path = self.listview3.GetItem(selected, 1).GetText()

        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        # cursor.execute('DELETE FROM

        cursor.execute('DELETE FROM files WHERE full_path = ?', (full_path,))
        conn.commit()
        conn.close()

        self.listview3.DeleteItem(selected)

        wx.MessageBox("Record deleted from the database.", "Info", wx.OK | wx.ICON_INFORMATION)

    def on_export_excel(self, event):
        if self.listview3.GetItemCount() == 0:
            wx.MessageBox("No data to export.", "Error", wx.OK | wx.ICON_ERROR)
            return

        with wx.FileDialog(self, "Save Excel file", wildcard="Excel files (*.xlsx)|*.xlsx",
                           style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as fileDialog:

            if fileDialog.ShowModal() == wx.ID_CANCEL:
                return

            pathname = fileDialog.GetPath()
            try:
                workbook = openpyxl.Workbook()
                sheet = workbook.active
                sheet.title = "Python Files"

                # Write headers
                headers = ["File Name", "Full Path", "Date Modified", "Remarks", "Valid"]
                for col, header in enumerate(headers, start=1):
                    sheet.cell(row=1, column=col, value=header)

                # Write data
                for row in range(self.listview3.GetItemCount()):
                    for col in range(self.listview3.GetColumnCount()):
                        value = self.listview3.GetItem(row, col).GetText()
                        sheet.cell(row=row+2, column=col+1, value=value)

                workbook.save(pathname)
                wx.MessageBox(f"Data exported to {pathname}", "Info", wx.OK | wx.ICON_INFORMATION)
            except Exception as e:
                wx.MessageBox(f"Failed to export data: {str(e)}", "Error", wx.OK | wx.ICON_ERROR)

class EditDialog(wx.Dialog):
    def __init__(self, parent, remarks, valid):
        super().__init__(parent, title="Edit Record", size=(350, 200))

        vbox = wx.BoxSizer(wx.VERTICAL)

        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        lbl1 = wx.StaticText(self, label="Remarks:")
        self.remarks_ctrl = wx.TextCtrl(self, value=remarks, style=wx.TE_MULTILINE)
        hbox1.Add(lbl1, flag=wx.ALL, border=5)
        hbox1.Add(self.remarks_ctrl, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        lbl2 = wx.StaticText(self, label="Valid:")
        self.valid_checkbox = wx.CheckBox(self)
        self.valid_checkbox.SetValue(valid)
        hbox2.Add(lbl2, flag=wx.ALL, border=5)
        hbox2.Add(self.valid_checkbox, flag=wx.ALL, border=5)

        hbox3 = wx.BoxSizer(wx.HORIZONTAL)
        ok_btn = wx.Button(self, label="OK")
        ok_btn.Bind(wx.EVT_BUTTON, self.on_ok)
        cancel_btn = wx.Button(self, label="Cancel")
        cancel_btn.Bind(wx.EVT_BUTTON, self.on_cancel)
        hbox3.Add(ok_btn, flag=wx.ALL, border=5)
        hbox3.Add(cancel_btn, flag=wx.ALL, border=5)

        vbox.Add(hbox1, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
        vbox.Add(hbox2, flag=wx.ALIGN_CENTER | wx.ALL, border=10)
        vbox.Add(hbox3, flag=wx.ALIGN_CENTER | wx.ALL, border=10)

        self.SetSizer(vbox)

    def on_ok(self, event):
        self.EndModal(wx.ID_OK)

    def on_cancel(self, event):
        self.EndModal(wx.ID_CANCEL)

    def get_values(self):
        remarks = self.remarks_ctrl.GetValue()
        valid = "Yes" if self.valid_checkbox.GetValue() else "No"
        return remarks, valid

class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame()
        frame.Show()
        return True

if __name__ == "__main__":
    app = MyApp(False)
    app.MainLoop()                       

应用概述

这个应用程序提供了一个图形用户界面,允许用户浏览文件系统,查看和管理Python源代码文件。它的主要功能包括:

  1. 扫描指定文件夹中的所有.py文件
  2. 在列表视图中显示文件信息
  3. 搜索文件
  4. 编辑文件备注和有效性标志
  5. 将文件信息保存到SQLite数据库
  6. 从数据库中检索和显示文件信息
  7. 在Visual Studio Code中打开选定的文件
  8. 将文件信息导出到Excel

让我们深入了解这个应用的一些关键特性和它们的实现方式。

核心功能解析

1. 文件扫描和显示

应用程序使用Python的os模块来遍历指定文件夹及其子文件夹,查找所有的.py文件。文件信息(包括文件名、完整路径和修改日期)被收集并按最近修改日期排序,然后显示在一个wx.ListCtrl控件中。

python 复制代码
def on_scan(self, event):
    folder_path = self.folder_picker.GetPath()
    if not folder_path:
        wx.MessageBox("Please select a folder.", "Error", wx.OK | wx.ICON_ERROR)
        return

    self.listview1.DeleteAllItems()

    py_files = []
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            if file.endswith(".py"):
                full_path = os.path.join(root, file)
                date_modified = os.path.getmtime(full_path)
                date_str = wx.DateTime.FromTimeT(int(date_modified)).FormatISOCombined()
                py_files.append((file, full_path, date_str, date_modified))

    # Sort files by date modified (most recent first)
    py_files.sort(key=lambda x: x[3], reverse=True)

    for file, full_path, date_str, _ in py_files:
        index = self.listview1.InsertItem(self.listview1.GetItemCount(), file)
        self.listview1.SetItem(index, 1, full_path)
        self.listview1.SetItem(index, 2, date_str)

2. 文件搜索

搜索功能允许用户在文件名或完整路径中查找匹配项。匹配的项目会被高亮显示,使用户能够快速定位所需的文件。

python 复制代码
def search_in_listview(self, listview, search_term):
    for i in range(listview.GetItemCount()):
        item = listview.GetItem(i)
        if search_term in item.GetText().lower() or search_term in listview.GetItem(i, 1).GetText().lower():
            item.SetBackgroundColour(wx.YELLOW)
            listview.SetItem(item)
            listview.EnsureVisible(i)
        else:
            item.SetBackgroundColour(wx.WHITE)
            listview.SetItem(item)

    if not search_term:
        for i in range(listview.GetItemCount()):
            item = listview.GetItem(i)
            item.SetBackgroundColour(wx.WHITE)
            listview.SetItem(item)

3. 数据库集成

应用程序使用SQLite数据库来持久化文件信息。用户可以将文件信息保存到数据库,也可以从数据库中检索信息。这个功能特别有用,因为它允许用户在不同的会话中保留他们的文件管理状态。

python 复制代码
def save_to_database(self, event):
    try:
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()

        # Ensure table exists
        cursor.execute('''CREATE TABLE IF NOT EXISTS files (
                            id INTEGER PRIMARY KEY AUTOINCREMENT,
                            file_name TEXT,
                            full_path TEXT,
                            date_modified TEXT,
                            remarks TEXT,
                            valid INTEGER)''')

        # Append new records or update existing ones
        for index in range(self.listview2.GetItemCount()):
            file_name = self.listview2.GetItemText(index)
            full_path = self.listview2.GetItem(index, 1).GetText()
            date_modified = self.listview2.GetItem(index, 2).GetText()
            remarks = self.listview2.GetItem(index, 3).GetText()
            valid = self.listview2.GetItem(index, 4).GetText()
            valid = 1 if valid == "Yes" else 0

            # Check if the record already exists
            cursor.execute('SELECT * FROM files WHERE full_path = ?', (full_path,))
            if cursor.fetchone() is None:
                # If it doesn't exist, insert a new record
                cursor.execute('INSERT INTO files (file_name, full_path, date_modified, remarks, valid) VALUES (?, ?, ?, ?, ?)',
                            (file_name, full_path, date_modified, remarks, valid))
            else:
                # If it exists, update the existing record
                cursor.execute('UPDATE files SET file_name = ?, date_modified = ?, remarks = ?, valid = ? WHERE full_path = ?',
                            (file_name, date_modified, remarks, valid, full_path))

        conn.commit()
    except sqlite3.Error as e:
        wx.MessageBox(f"Database error: {e}", "Error", wx.OK | wx.ICON_ERROR)
    finally:
        conn.close()

    wx.MessageBox("Data saved to the database.", "Info", wx.OK | wx.ICON_INFORMATION)

4. 与Visual Studio Code集成

为了提高开发效率,应用程序允许用户直接在Visual Studio Code中打开选定的Python文件。这是通过使用Python的subprocess模块来启动VS Code实现的。

python 复制代码
def open_in_vscode(self, listview):
    selected = listview.GetFirstSelected()
    if selected == -1:
        wx.MessageBox("Please select a file to open", "Error", wx.OK | wx.ICON_ERROR)
        return

    full_path = listview.GetItem(selected, 1).GetText()
    subprocess.Popen(["C:\\Users\\86182\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe", full_path])

5. 导出到Excel

为了方便数据共享和报告生成,应用程序提供了将文件信息导出到Excel的功能。这是使用openpyxl库实现的。

python 复制代码
def on_export_excel(self, event):
    if self.listview3.GetItemCount() == 0:
        wx.MessageBox("No data to export.", "Error", wx.OK | wx.ICON_ERROR)
        return

    with wx.FileDialog(self, "Save Excel file", wildcard="Excel files (*.xlsx)|*.xlsx",
                       style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as fileDialog:

        if fileDialog.ShowModal() == wx.ID_CANCEL:
            return

        pathname = fileDialog.GetPath()
        try:
            workbook = openpyxl.Workbook()
            sheet = workbook.active
            sheet.title = "Python Files"

            # Write headers
            headers = ["File Name", "Full Path", "Date Modified", "Remarks", "Valid"]
            for col, header in enumerate(headers, start=1):
                sheet.cell(row=1, column=col, value=header)

            # Write data
            for row in range(self.listview3.GetItemCount()):
                for col in range(self.listview3.GetColumnCount()):
                    value = self.listview3.GetItem(row, col).GetText()
                    sheet.cell(row=row+2, column=col+1, value=value)

            workbook.save(pathname)
            wx.MessageBox(f"Data exported to {pathname}", "Info", wx.OK | wx.ICON_INFORMATION)
        except Exception as e:
            wx.MessageBox(f"Failed to export data: {str(e)}", "Error", wx.OK | wx.ICON_ERROR)

效果如下

结论

这个Python文件管理器应用程序展示了如何使用Python和wxPython创建一个功能丰富的桌面应用。它不仅提供了基本的文件管理功能,还集成了数据库持久化、外部编辑器启动和数据导出等高级特性。

相关推荐
没书读了几秒前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·8 分钟前
java基础面试题笔记(基础篇)
java·笔记·python
i道i32 分钟前
MySQL win安装 和 pymysql使用示例
数据库·mysql
小怪兽ysl33 分钟前
【PostgreSQL使用pg_filedump工具解析数据文件以恢复数据】
数据库·postgresql
wqq_9922502771 小时前
springboot基于微信小程序的食堂预约点餐系统
数据库·微信小程序·小程序
爱上口袋的天空1 小时前
09 - Clickhouse的SQL操作
数据库·sql·clickhouse
小喵要摸鱼2 小时前
Python 神经网络项目常用语法
python
聂 可 以3 小时前
Windows环境安装MongoDB
数据库·mongodb
web前端神器3 小时前
mongodb多表查询,五个表查询
数据库·mongodb
门牙咬脆骨3 小时前
【Redis】redis缓存击穿,缓存雪崩,缓存穿透
数据库·redis·缓存