首页 > 编程语言 >Python文件管理器:一个基于wxPython的桌面应用

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

时间:2024-08-24 12:25:49浏览次数:12  
标签:listview2 full 管理器 Python self wxPython path listview wx

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

全部代码

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控件中。

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. 文件搜索

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

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数据库来持久化文件信息。用户可以将文件信息保存到数据库,也可以从数据库中检索信息。这个功能特别有用,因为它允许用户在不同的会话中保留他们的文件管理状态。

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实现的。

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库实现的。

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创建一个功能丰富的桌面应用。它不仅提供了基本的文件管理功能,还集成了数据库持久化、外部编辑器启动和数据导出等高级特性。

标签:listview2,full,管理器,Python,self,wxPython,path,listview,wx
From: https://blog.csdn.net/winniezhang/article/details/141310091

相关文章

  • Python之QRCode
    方法一:生成二维码importqrcode#生成二维码img=qrcode.make(data="你好")#将二维码保存为图片withopen('qrcode_test.png','wb')asf:img.save(f)解码二维码importcv2d=cv2.QRCodeDetector()val,_,_=d.detectAndDecode(cv2.imread('qrcode......
  • 计算机毕业设计推荐-基于python的医院预约门诊平台
    精彩专栏推荐订阅:在下方专栏......
  • 计算机毕业设计推荐-基于python的无人超市管理系统
    精彩专栏推荐订阅:在下方主页......
  • Python小白自用学习日记 | print和input函数(参考“Python_子木”的教程)&pandas的下载
            写论文要分析气象数据,下载后发现是txt格式,看来要学学python做数据处理。真是“书到用时方恨少”。我看的是B站“Python_子木”的教程。电脑里以前装过了VScode,就暂时不下载pycharm了。        仅作为一个超级小白的养成系学习日记吧。大佬们请不用点......
  • 下载小说时,python字符集编码utf-8和GBK的错误处理(慎!)
    创作背景  今天想找本小说看,但是居然只能在网页上能找到资源,作为一名测试工程师,这能忍?多么严重的体验,这还能一起愉快的玩耍了吗?还能好好摸鱼了吗?  果断花点时间,查看页面结构,写个脚本自动请求网页,获取小说内容,并进行储存到本地txt文件中,放在手机里,躺在床上慢慢看。没......
  • python Logging 模块的日志参数配置及使用
    官方文档查看路径:logging---Python的日志记录工具—Python3.12.5文档步骤一:先建立log.conf文件步骤二:在基类文件中引用log.conf文件,并创建Logger日志记录器--步骤一-----------------------log.conf文件配置信息[loggers]keys=root,infoLogger[logger_root......
  • 十大免费的Python爬虫APP!再也不用开那么多会员了!
      在探讨十大网络爬虫免费App时,需要注意的是,并非所有提到的工具都完全免费或以App形式存在。不过,我可以根据当前可用的信息和市场情况,列出一些广受欢迎且部分功能可能免费的网络爬虫工具或软件,尽管其中一些可能主要是桌面应用或框架。以下是按照您的要求整理的列表:1.八爪......
  • Python编码系列—Python单元测试的艺术:深入探索unittest与pytest
    ......
  • Python脚本
    1.对目录下的文件进行分类,并根据文件后缀,将相应文件移动或拷贝至对应目录importsysimportosimportshutildefget_file_extension(filename):_,file_extension=os.path.splitext(filename)iffile_extension.startswith('.'):returnf......
  • Python的OpenCV转换图像大小
    在Python中,使用OpenCV库来转换图像大小是一个常见的操作,它可以帮助你调整图像到特定的尺寸,以适应不同的应用场景,比如图像预处理、模型输入等。下面是一个详细的代码示例,展示了如何使用OpenCV来转换图像的大小。首先,确保你已经安装了OpenCV库。如果还没有安装,可以通过pip安装:bash......