python:psutil获取指定进程Cpu及Memory使用的GUI界面

1导入依赖库

import os
import psutil
import time
from pyecharts import options as opts
from pyecharts.charts import Line
import PySimpleGUI as sg
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor
import ctypes
import sys

2主界面及功能设计

class ScatterPlotGUI:
    def __init__(self):
        self.loc_path = os.getcwd()
        self.errorLog_path = os.path.join(self.loc_path, "errorLog")
        self.fig_save_path_folder = os.path.join(self.loc_path, "ReportFile")
        self.fig_save_path = ""
        self.process_names = ""  
        self.running = False
        self.delay = 0
        self.executor = ThreadPoolExecutor(max_workers=1)
        sg.theme('BrownBlue')  
        self.win_main = sg.Window('getCpuAndMemory', self.main_layout(), font=("Times New Roman", 15),size=(400, 100))

    def main_layout(self):  # 程序主界面
        layout_file = []
        file_frame = [
            [
                sg.Text('ProcessName(exe):', font=("Times New Roman", 9)),
                sg.Input(key='-process_names-', size=(4, 1), default_text="msedge.exe",justification='center',font=("Times New Roman", 9), expand_x=True, enable_events=True),#
                sg.Text('CountIntervals(s):', font=("Times New Roman", 9)),
                sg.Input(key='-delay-', size=(4, 1), default_text="3", justification='center', font=("Times New Roman", 9), expand_x=True, enable_events=True),  #
            ],

            [
                sg.Button('On', key='-start-', size=(10, 1), font=("Times New Roman", 9), expand_x=True, disabled=False),
                sg.Button('Off', key='-stop-', size=(10, 1), font=("Times New Roman", 9), expand_x=True, disabled=True),
                sg.Button('EXIT', key='-EXIT-', font=("Times New Roman", 9), expand_x=True),
            ],

        ]
        layout_file.append([sg.Frame(layout=file_frame, title="getCpuAndMemory", expand_x=True, font=("Times New Roman", 8))])
        return layout_file

    def run(self):
        if not os.path.exists(self.fig_save_path_folder):  # fig_save_path_folder
            os.mkdir(self.fig_save_path_folder)
        time_path = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')

        while True:
            ##task_pool = ThreadPoolExecutor(max_workers=1)
            event_main, value_main = self.win_main.Read()
            self.fig_save_path = os.path.join(self.fig_save_path_folder, time_path)
            self.process_names = value_main['-process_names-']
            self.delay = int(value_main['-delay-'])

            if event_main in (sg.WINDOW_CLOSED, "-EXIT-"):
                break
            elif event_main == '-process_names-':
                self.win_main['-start-'].update(disabled=False)
            elif event_main == '-start-':
                if not os.path.exists(self.fig_save_path):
                    os.mkdir(self.fig_save_path)
                self.start_accumulator()
            elif event_main == '-stop-':
                self.stop_accumulator()

    def getCpuAndMemory(self, process_names):
    # 存储内存和CPU占用数据的变量
        total_memory = 0
        total_cpu = 0
        # 获取指定进程的信息
        pids = psutil.pids()
        for pid in pids:

            try:
                p = psutil.Process(pid)
                if p.name() in process_names:
                    # 获取进程的内存和CPU占用情况
                    # process.memory_info()
                    # rss: 该进程实际使用物理内存(包含共享库占用的全部内存,不包括共享内存和映射文件等)。
                    # vms:该进程使用的虚拟内存总量。
                    # uss: 进程的所有占用的私有物理内存大小,包括私有物理内存、共享内存和映射文件等。
                    #mem = p.memory_info().rss / (1024 ** 2)  # 单位:MB
                    mem = p.memory_full_info().uss / (1024 ** 2)  # 单位:MB  #更准确
                    cpu = p.cpu_percent(interval=0.5)
                    # 累加内存和CPU占用量
                    total_memory += mem
                    total_cpu += cpu
                    #print("==>>> processName:%s   processStatus:%s   processMememory:%.4f   processCPU:%.4f <<<==" % (p.name(), p.status(), mem, cpu))


            except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess) as e:
                pass
            # except psutil.NoSuchProcess as e1:
            #     #print("no process found with pid=&s" % pid)
            #     print("@NoSuchProcess>>> ", e1)
            #     pass
            # except psutil.AccessDenied as e2:
            #     #print("no process found with pid=&s" % pid)
            #     print("@AccessDenied>>> ", e2)
            #     pass
            # except psutil.ZombieProcess as e3:
            #     #print("no process found with pid=&s" % pid)
            #     print("@ZombieProcess>>> ", e3)
            #     pass

        print("==>>> %s   processName:%s   TotalMememory:%.4f   TotalCPU:%.4f <<<==" % (time.strftime('%Y-%m-%d %H:%M:%S'), process_names, total_memory, total_cpu))
        # 判断目录下是否已存在 memory.txt 和 cpu.txt 文件
        memory_txt = os.path.join(self.fig_save_path,'%s_memory.txt'%self.process_names[:-4])
        cpu_txt = os.path.join(self.fig_save_path, '%s_cpu.txt'%self.process_names[:-4])
        if not os.path.isfile(memory_txt):
            with open(memory_txt, 'w') as f:
                pass
        if not os.path.isfile(cpu_txt):
            with open(cpu_txt, 'w') as f:
                pass
        finalMemory = '%.3f' % total_memory
        finalCPU = '%.3f' % total_cpu
        # 将总的内存和CPU占用量写入文件, a表示追加数据
        with open(memory_txt, 'a') as f:
            f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} {finalMemory}\n")
        with open(cpu_txt, 'a') as f:
            f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} {finalCPU}\n")


    def generateCpuAndMemoryReport(self, process_names):
        try:
            while self.running:
            #获取内存和CPU数据
                self.getCpuAndMemory(process_names)
                # 获取当前脚本所在的目录
                memory_txt = os.path.join(self.fig_save_path, '%s_memory.txt'%self.process_names[:-4])
                cpu_txt = os.path.join(self.fig_save_path, '%s_cpu.txt'%self.process_names[:-4])
                memory_html = os.path.join(self.fig_save_path, '%s_memory_monitor_report.html'%self.process_names[:-4])
                cpu_html = os.path.join(self.fig_save_path, '%s_cpu_monitor_report.html'%self.process_names[:-4])
                # 获取内存折线图需要绘制的数据信息
                x = []
                y = []
                with open(memory_txt) as f:
                    for line in f:
                        space_index = line.find(' ')
                        if space_index != -1:
                            data = line[space_index + 1:]  # 切片操作,保留空格之后的部分
                            time0, per = data.strip().split()
                            x.append(time0)
                            y.append(float(per))  # 将字符串转换为浮点数

                line = (
                    Line()
                    .add_xaxis(x)
                    .add_yaxis("", y, label_opts=opts.LabelOpts(is_show=False))
                    .set_global_opts(title_opts=opts.TitleOpts(title="内存使用监控,单位:M"))
                )

                line.render(path=memory_html)

                # 获取cpu折线图需要绘制的数据信息
                x = []
                y = []
                with open(cpu_txt) as f:
                    for line in f:
                        space_index = line.find(' ')
                        if space_index != -1:
                            data = line[space_index + 1:]  # 切片操作,保留空格之后的部分
                            time1, per = data.strip().split()
                            x.append(time1)
                            y.append(float(per))  # 将字符串转换为浮点数

                line = (
                    Line()
                    .add_xaxis(x)
                    .add_yaxis("", y, label_opts=opts.LabelOpts(is_show=False))
                    .set_global_opts(title_opts=opts.TitleOpts(title="cpu使用监控,单位:百分比"))
                )

                line.render(path=cpu_html)
                time.sleep(self.delay)
        except Exception as e:
            print("@error>>> ", e)

    def close(self):
        self.win_main.close()
        self.executor.shutdown(wait=True)

    def start_accumulator(self):
        if not self.running:
            self.running = True
            self.win_main['-start-'].update(disabled=True)
            self.win_main['-stop-'].update(disabled=False)
            self.executor.submit(self.generateCpuAndMemoryReport, self.process_names)

    def stop_accumulator(self):
        if self.running:
            self.running = False
            self.win_main['-start-'].update(disabled=False)
            self.win_main['-stop-'].update(disabled=True)
            print("------------------>-->>-->>> Execution stopped <<<--<<--<------------------")

3获取管理员权限执行

def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

4主程序

if __name__ == '__main__':

    if not is_admin():
        ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)
        sys.exit()
    mygui = ScatterPlotGUI()
    mygui.run()
    mygui.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值