使用 Python构建 Windows 进程管理器应用程序

在这篇博客中,我们将探讨如何使用 wxPython 构建一个简单的 Windows 进程管理器应用程序。这个应用程序允许用户列出当前系统上的所有进程,选择和终止进程,并将特定进程保存到文件中以供将来加载。

C:\pythoncode\new\manageprocess.py

全部代码

python 复制代码
import wx
import psutil
import os
import signal

class ProcessManager(wx.Frame):
    def __init__(self, parent, title):
        super(ProcessManager,self).__init__(parent, title=title, size=(800, 500))

        self.panel = wx.Panel(self)

        self.search_box = wx.TextCtrl(self.panel, style=wx.TE_PROCESS_ENTER)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnSearchProcess, self.search_box)

        self.btn_list_processes = wx.Button(self.panel, label='List All Processes')

        # Create ListView1 with a checkbox column
        self.process_listview = wx.ListView(self.panel, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
        self.process_listview.InsertColumn(0, '', width=40)  # Checkbox column
        self.process_listview.InsertColumn(1, 'Process Name', width=200)
        self.process_listview.InsertColumn(2, 'PID', width=100)
        self.process_listview.InsertColumn(3, 'CPU %', width=100)
        self.process_listview.InsertColumn(4, 'RAM %', width=100)

        self.selected_listview = wx.ListView(self.panel, style=wx.LC_REPORT)
        self.selected_listview.InsertColumn(0, 'Process Name', width=200)
        self.selected_listview.InsertColumn(1, 'PID', width=100)

        self.btn_select_all = wx.Button(self.panel, label='Select All')
        self.btn_deselect_all = wx.Button(self.panel, label='Deselect All')
        self.btn_add_to_listview2 = wx.Button(self.panel, label='Add to ListView2')
        self.btn_kill_processes = wx.Button(self.panel, label='Kill Selected Processes')
        self.btn_kill_by_name = wx.Button(self.panel, label='Kill by Name')
        self.btn_save = wx.Button(self.panel, label='Save')
        self.btn_load = wx.Button(self.panel, label='Load')
        self.btn_delete_selected = wx.Button(self.panel, label='Delete Selected')

        # Organize layout with BoxSizers
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        search_sizer = wx.BoxSizer(wx.HORIZONTAL)
        listview1_sizer = wx.BoxSizer(wx.VERTICAL)
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        listview2_sizer = wx.BoxSizer(wx.VERTICAL)

        search_sizer.Add(self.search_box, 1, wx.EXPAND | wx.ALL, 5)
        search_sizer.Add(self.btn_list_processes, 0, wx.EXPAND | wx.ALL, 5)

        listview1_sizer.Add(search_sizer, 0, wx.EXPAND | wx.ALL, 5)
        listview1_sizer.Add(self.process_listview, 1, wx.EXPAND | wx.ALL, 5)

        button_sizer.Add(self.btn_select_all, 0, wx.EXPAND | wx.ALL, 5)
        button_sizer.Add(self.btn_deselect_all, 0, wx.EXPAND | wx.ALL, 5)
        button_sizer.Add(self.btn_add_to_listview2, 0, wx.EXPAND | wx.ALL, 5)

        listview1_sizer.Add(button_sizer, 0, wx.ALIGN_CENTER | wx.ALL, 5)

        listview2_sizer.Add(self.selected_listview, 1, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_kill_processes, 0, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_kill_by_name, 0, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_save, 0, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_load, 0, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_delete_selected, 0, wx.EXPAND | wx.ALL, 5)

        main_sizer.Add(listview1_sizer, 1, wx.EXPAND | wx.ALL, 5)
        main_sizer.Add(listview2_sizer, 1, wx.EXPAND | wx.ALL, 5)

        self.panel.SetSizer(main_sizer)

        self.Bind(wx.EVT_BUTTON, self.OnListProcesses, self.btn_list_processes)
        self.Bind(wx.EVT_BUTTON, self.OnKillProcesses, self.btn_kill_processes)
        self.Bind(wx.EVT_BUTTON, self.OnKillProcessesByName, self.btn_kill_by_name)
        self.Bind(wx.EVT_BUTTON, self.OnSaveProcesses, self.btn_save)
        self.Bind(wx.EVT_BUTTON, self.OnLoadProcesses, self.btn_load)
        self.Bind(wx.EVT_BUTTON, self.OnSelectAll, self.btn_select_all)
        self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, self.btn_deselect_all)
        self.Bind(wx.EVT_BUTTON, self.OnAddToListView2, self.btn_add_to_listview2)
        self.Bind(wx.EVT_BUTTON, self.OnDeleteSelected, self.btn_delete_selected)

        self.Show()

    def OnListProcesses(self,event):
        self.process_listview.DeleteAllItems()
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            index = self.process_listview.InsertItem(self.process_listview.GetItemCount(), '')
            self.process_listview.SetItem(index, 1, proc.info['name'])
            self.process_listview.SetItem(index, 2, str(proc.info['pid']))
            self.process_listview.SetItem(index, 3, f"{proc.info['cpu_percent']:.1f}")
            self.process_listview.SetItem(index, 4, f"{proc.info['memory_percent']:.1f}")

    def OnSearchProcess(self,event):
        search_query = self.search_box.GetValue().lower()
        self.process_listview.DeleteAllItems()
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            if search_query in proc.info['name'].lower():
                index = self.process_listview.InsertItem(self.process_listview.GetItemCount(), '')
                self.process_listview.SetItem(index, 1, proc.info['name'])
                self.process_listview.SetItem(index, 2, str(proc.info['pid']))
                self.process_listview.SetItem(index, 3, f"{proc.info['cpu_percent']:.1f}")
                self.process_listview.SetItem(index, 4, f"{proc.info['memory_percent']:.1f}")

    def OnKillProcesses(self,event):
        count = self.process_listview.GetItemCount()
        for i in range(count):
            if self.process_listview.GetItemState(i, wx.LIST_STATE_SELECTED):
                pid = int(self.process_listview.GetItemText(i, 2))
                try:
                    os.kill(pid, signal.SIGTERM)
                except Exception as e:
                    wx.MessageBox(f"Error killing process {pid}: {str(e)}", "Error", wx.OK | wx.ICON_ERROR)
        self.OnListProcesses(event)

    def OnKillProcessesByName(self,event):
        process_names = [self.selected_listview.GetItemText(i) for i in range(self.selected_listview.GetItemCount())]
        for proc in psutil.process_iter(['name', 'pid']):
            if proc.info['name'] in process_names:
                try:
                    os.kill(proc.info['pid'], signal.SIGTERM)
                except Exception as e:
                    wx.MessageBox(f"Error killing process {proc.info['pid']}: {str(e)}", "Error", wx.OK | wx.ICON_ERROR)

    def OnSaveProcesses(self,event):
        with open("processes.txt","w") as file:
            count = self.selected_listview.GetItemCount()
            for i in range(count):
                process_name = self.selected_listview.GetItemText(i)
                process_pid = self.selected_listview.GetItemText(i, 1)
                file.write(f"{process_name},{process_pid}\n")

    def OnLoadProcesses(self,event):
        self.selected_listview.DeleteAllItems()
        if os.path.exists("processes.txt"):
            with open("processes.txt","r") as file:
                for line in file:
                    process_name, process_pid = line.strip().split(',')
                    index = self.selected_listview.InsertItem(self.selected_listview.GetItemCount(), process_name)
                    self.selected_listview.SetItem(index, 1, process_pid)

    def OnSelectAll(self,event): 
        count = self.process_listview.GetItemCount()
        for i in range(count):
            self.process_listview.SetItemState(i, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)

    def OnDeselectAll(self,event):
        count = self.process_listview.GetItemCount()
        for i in range(count):
            self.process_listview.SetItemState(i, 0, wx.LIST_STATE_SELECTED)

    def OnAddToListView2(self,event):
        count = self.process_listview.GetItemCount()
        for i in range(count):
            if self.process_listview.GetItemState(i, wx.LIST_STATE_SELECTED):
                process_name = self.process_listview.GetItemText(i, 1)
                process_pid = self.process_listview.GetItemText(i, 2)
                index = self.selected_listview.InsertItem(self.selected_listview.GetItemCount(), process_name)
                self.selected_listview.SetItem(index, 1, process_pid)

    def OnDeleteSelected(self,event):
        count = self.selected_listview.GetItemCount()
        for i in range(count - 1, -1, -1):
            if self.selected_listview.GetItemState(i, wx.LIST_STATE_SELECTED):
                self.selected_listview.DeleteItem(i)

if __name__ == "__main__":
    app = wx.App(False)
    frame = ProcessManager(None, "Process Manager")
    app.MainLoop()

项目概述

我们的目标是构建一个图形用户界面 (GUI) 应用程序,主要功能包括:

  1. 列出所有进程:列出当前系统上的所有进程,并显示进程名、PID、CPU 和内存占用情况。
  2. 搜索进程:通过输入框搜索指定进程名称,并显示匹配结果。
  3. 选择和终止进程:通过复选框选择多个进程并终止它们。
  4. 保存和加载进程列表:将选定的进程保存到文本文件中,并从文件加载这些进程。
  5. 进程管理:添加功能来按名称终止进程,并从列表中删除选中的项。

准备工作

在开始之前,确保你已经安装了 Python 和 wxPython。你可以通过以下命令安装 wxPython:

bash 复制代码
pip install wxPython

构建应用程序

下面是我们将要实现的完整代码。你可以直接复制到你的 IDE 中并运行。

python 复制代码
import wx
import psutil
import os
import signal

class ProcessManager(wx.Frame):
    def __init__(self, parent, title):
        super(ProcessManager, self).__init__(parent, title=title, size=(800, 500))

        self.panel = wx.Panel(self)

        # 搜索框
        self.search_box = wx.TextCtrl(self.panel, style=wx.TE_PROCESS_ENTER)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnSearchProcess, self.search_box)

        # 列出所有进程按钮
        self.btn_list_processes = wx.Button(self.panel, label='List All Processes')

        # 创建 ListView1 并添加复选框列
        self.process_listview = wx.ListView(self.panel, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
        self.process_listview.InsertColumn(0, '', width=40)  # 复选框列
        self.process_listview.InsertColumn(1, 'Process Name', width=200)
        self.process_listview.InsertColumn(2, 'PID', width=100)
        self.process_listview.InsertColumn(3, 'CPU %', width=100)
        self.process_listview.InsertColumn(4, 'RAM %', width=100)

        self.selected_listview = wx.ListView(self.panel, style=wx.LC_REPORT)
        self.selected_listview.InsertColumn(0, 'Process Name', width=200)
        self.selected_listview.InsertColumn(1, 'PID', width=100)

        # 各种功能按钮
        self.btn_select_all = wx.Button(self.panel, label='Select All')
        self.btn_deselect_all = wx.Button(self.panel, label='Deselect All')
        self.btn_add_to_listview2 = wx.Button(self.panel, label='Add to ListView2')
        self.btn_kill_processes = wx.Button(self.panel, label='Kill Selected Processes')
        self.btn_kill_by_name = wx.Button(self.panel, label='Kill by Name')
        self.btn_save = wx.Button(self.panel, label='Save')
        self.btn_load = wx.Button(self.panel, label='Load')
        self.btn_delete_selected = wx.Button(self.panel, label='Delete Selected')

        # 使用 BoxSizers 组织布局
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        search_sizer = wx.BoxSizer(wx.HORIZONTAL)
        listview1_sizer = wx.BoxSizer(wx.VERTICAL)
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        listview2_sizer = wx.BoxSizer(wx.VERTICAL)

        # 将搜索框和按钮添加到布局中
        search_sizer.Add(self.search_box, 1, wx.EXPAND | wx.ALL, 5)
        search_sizer.Add(self.btn_list_processes, 0, wx.EXPAND | wx.ALL, 5)

        # 将 ListView1 和按钮添加到布局中
        listview1_sizer.Add(search_sizer, 0, wx.EXPAND | wx.ALL, 5)
        listview1_sizer.Add(self.process_listview, 1, wx.EXPAND | wx.ALL, 5)

        button_sizer.Add(self.btn_select_all, 0, wx.EXPAND | wx.ALL, 5)
        button_sizer.Add(self.btn_deselect_all, 0, wx.EXPAND | wx.ALL, 5)
        button_sizer.Add(self.btn_add_to_listview2, 0, wx.EXPAND | wx.ALL, 5)

        listview1_sizer.Add(button_sizer, 0, wx.ALIGN_CENTER | wx.ALL, 5)

        # 将 ListView2 和其他按钮添加到布局中
        listview2_sizer.Add(self.selected_listview, 1, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_kill_processes, 0, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_kill_by_name, 0, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_save, 0, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_load, 0, wx.EXPAND | wx.ALL, 5)
        listview2_sizer.Add(self.btn_delete_selected, 0, wx.EXPAND | wx.ALL, 5)

        main_sizer.Add(listview1_sizer, 1, wx.EXPAND | wx.ALL, 5)
        main_sizer.Add(listview2_sizer, 1, wx.EXPAND | wx.ALL, 5)

        self.panel.SetSizer(main_sizer)

        # 绑定事件处理
        self.Bind(wx.EVT_BUTTON, self.OnListProcesses, self.btn_list_processes)
        self.Bind(wx.EVT_BUTTON, self.OnKillProcesses, self.btn_kill_processes)
        self.Bind(wx.EVT_BUTTON, self.OnKillProcessesByName, self.btn_kill_by_name)
        self.Bind(wx.EVT_BUTTON, self.OnSaveProcesses, self.btn_save)
        self.Bind(wx.EVT_BUTTON, self.OnLoadProcesses, self.btn_load)
        self.Bind(wx.EVT_BUTTON, self.OnSelectAll, self.btn_select_all)
        self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, self.btn_deselect_all)
        self.Bind(wx.EVT_BUTTON, self.OnAddToListView2, self.btn_add_to_listview2)
        self.Bind(wx.EVT_BUTTON, self.OnDeleteSelected, self.btn_delete_selected)

        self.Show()

    def OnListProcesses(self, event):
        self.process_listview.DeleteAllItems()
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            index = self.process_listview.InsertItem(self.process_listview.GetItemCount(), '')
            self.process_listview.SetItem(index, 1, proc.info['name'])
            self.process_listview.SetItem(index, 2, str(proc.info['pid']))
            self.process_listview.SetItem(index, 3, f"{proc.info['cpu_percent']:.1f}")
            self.process_listview.SetItem(index, 4, f"{proc.info['memory_percent']:.1f}")

    def OnSearchProcess(self, event):
        search_query = self.search_box.GetValue().lower()
        self.process_listview.DeleteAllItems()
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            if search_query in proc.info['name'].lower():
                index = self.process_listview.InsertItem(self.process_listview.GetItemCount(), '')
                self.process_listview.SetItem(index, 1, proc.info['name'])
                self.process_listview.SetItem(index, 2, str(proc.info['pid']))
                self.process_listview.SetItem(index, 3, f"{proc.info['cpu_percent']:.1f}")
                self.process_listview.SetItem(index, 4, f"{proc.info['memory_percent']:.1f}")

    def OnKillProcesses(self, event):
        count = self.process_listview.GetItemCount()
        for i in range(count):
            if self.process_listview.GetItemState(i, wx.LIST_STATE_SELECTED):
                pid = int(self.process_listview.GetItemText(i, 2))
                try:
                    os.kill(pid, signal.SIGTERM)
                except Exception as e:
                    wx.MessageBox(f"Error killing process {pid}: {str(e)}", "Error", wx.OK | wx.ICON_ERROR)
        self.OnListProcesses(event)

    def OnKillProcessesByName(self, event):
        process_names = [self.selected_listview.GetItemText(i) for i in range(self.selected_listview.GetItemCount())]
        for proc in psutil.process_iter(['name', 'pid']):
            if proc.info['name'] in process_names:
                try:
                    os.kill(proc.info['pid'], signal.SIGTERM)
                except Exception as e:
                    wx.MessageBox(f"Error killing process {proc.info['pid']}: {str(e)}", "Error", wx.OK | wx.ICON_ERROR)

    def OnSaveProcesses(self, event):
        with open

('saved_processes.txt', 'w') as f:
            for i in range(self.selected_listview.GetItemCount()):
                process_name = self.selected_listview.GetItemText(i)
                process_pid = self.selected_listview.GetItemText(i, 1)
                f.write(f"{process_name},{process_pid}\n")

    def OnLoadProcesses(self, event):
        self.selected_listview.DeleteAllItems()
        try:
            with open('saved_processes.txt', 'r') as f:
                for line in f.readlines():
                    process_name, process_pid = line.strip().split(',')
                    index = self.selected_listview.InsertItem(self.selected_listview.GetItemCount(), process_name)
                    self.selected_listview.SetItem(index, 1, process_pid)
        except FileNotFoundError:
            wx.MessageBox("No saved processes found.", "Error", wx.OK | wx.ICON_ERROR)

    def OnSelectAll(self, event):
        count = self.process_listview.GetItemCount()
        for i in range(count):
            self.process_listview.CheckItem(i)

    def OnDeselectAll(self, event):
        count = self.process_listview.GetItemCount()
        for i in range(count):
            self.process_listview.CheckItem(i, False)

    def OnAddToListView2(self, event):
        count = self.process_listview.GetItemCount()
        for i in range(count):
            if self.process_listview.IsItemChecked(i):
                process_name = self.process_listview.GetItemText(i, 1)
                process_pid = self.process_listview.GetItemText(i, 2)
                index = self.selected_listview.InsertItem(self.selected_listview.GetItemCount(), process_name)
                self.selected_listview.SetItem(index, 1, process_pid)

    def OnDeleteSelected(self, event):
        count = self.selected_listview.GetItemCount()
        for i in range(count - 1, -1, -1):
            if self.selected_listview.GetItemState(i, wx.LIST_STATE_SELECTED):
                self.selected_listview.DeleteItem(i)

if __name__ == "__main__":
    app = wx.App(False)
    frame = ProcessManager(None, "Process Manager")
    app.MainLoop()

代码解释

1. 初始化界面

ProcessManager 类的 __init__ 方法中,我们设置了窗口的基本布局,并添加了所有必要的控件,包括 ListView、按钮和搜索框。我们还绑定了所有按钮的事件处理方法。

2. 列出所有进程

OnListProcesses 方法中,我们使用 psutil.process_iter 获取所有正在运行的进程,并将它们显示在 ListView1 中。我们显示了进程名称、PID、CPU 使用率和内存使用率。

3. 搜索进程

OnSearchProcess 方法通过搜索框输入的内容进行过滤,并在 ListView1 中显示匹配的进程。

4. 选择和终止进程

我们可以使用复选框选择一个或多个进程,并通过 OnKillProcessesOnKillProcessesByName 方法终止它们。

5. 保存和加载进程列表

OnSaveProcesses 方法将选中的进程保存到一个文本文件中,而 OnLoadProcesses 方法则从文件加载这些进程并显示在 ListView2 中。

6. 全选和全不选

通过 OnSelectAllOnDeselectAll 方法,我们可以选择或取消选择 ListView1 中的所有项。

效果如下

总结

这个小型的进程管理器应用程序展示了如何使用 wxPython 构建一个功能强大的桌面应用。通过整合 psutil 和 wxPython,我们可以轻松地管理和监控系统进程,为用户提供了便捷的工具。

你可以进一步扩展这个应用程序,例如添加更多的进程管理功能,或者优化界面布局和用户体验。希望这篇博客对你有所帮助,并激发你在 Python 开发中的更多创意!

相关推荐
tjjucheng5 小时前
靠谱的小程序定制开发哪个好
python
num_killer5 小时前
小白的Langchain学习
java·python·学习·langchain
WangYaolove13145 小时前
基于深度学习的中文情感分析系统(源码+文档)
python·深度学习·django·毕业设计·源码
自学不成才6 小时前
深度复盘:一次flutter应用基于内存取证的黑盒加密破解实录并完善算法推理助手
c++·python·算法·数据挖掘
徐先生 @_@|||7 小时前
Palantir Foundry 五层架构模型详解
开发语言·python·深度学习·算法·机器学习·架构
深蓝电商API7 小时前
Scrapy爬虫限速与并发控制最佳实践
爬虫·python·scrapy
Derrick__17 小时前
淘宝MD5爬虫
爬虫·python
薛定谔的猫19827 小时前
llama-index Embedding 落地到 RAG 系统
开发语言·人工智能·python·llama-index
玖釉-8 小时前
[Vulkan 学习之路] 08 - 给图片穿马甲:图像视图 (Image Views)
c++·windows·图形渲染
nimadan129 小时前
**手机小说扫榜工具2025推荐,精准追踪榜单动态与题材风向
python·智能手机