导航

Qt Designer 获取cpu和内存并以图表形式展现

Posted on 2022-04-01 18:51  初之萌萌  阅读(1049)  评论(0编辑  收藏  举报

功能:

1.随机值模拟cpu占用率和内存使用率

2.写入excel表格,以设备ip分工作表

3.折线图展现

 

效果图:

 

打开画图窗口,显示图表如下:

 

 

 perform.py代码:

import csv
import re
import time
import os
import sys
from xlutils.copy import copy
import telnetlib
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
import xlrd
import xlwt
from PyQt5.QtCore import QTimer, pyqtSignal, QDate, QTime, Qt, QObject
import pandas as pd
import random
from datetime import datetime
from PyQt5.QtWidgets import (QApplication, QFileDialog, QTableWidgetItem, QAbstractItemView, QHeaderView, QTableWidget,
    QFrame, QMainWindow)
from threading import Thread, Lock
from performance import Ui_MainWindow
from sub_window import UI

data_file = 'datas.xls'
lock = Lock()
timer_flag = False


def readCsvFile(file_path):
    '''
    从文件中读取行,以列表形式返回
    :return:
    '''
    iplists = []
    with open(file_path, 'r') as fp:
        reader = csv.reader(fp)
        for row in reader:
            iplists.append(row[0])
    return iplists

class TelnetClient():
    def __init__(self, ):
        self.tn = telnetlib.Telnet()

    # 此函数实现telnet登录主机
    def login_host(self, host_ip, username, password):
        try:
            # self.tn = telnetlib.Telnet(host_ip,port=23)
            self.tn.open(host_ip, port=23)
        except:
            return False
        self.tn.read_until(b'login: ', timeout=10)
        self.tn.write(username.encode('ascii') + b'\n')
        self.tn.read_until(b'Password: ', timeout=10)
        self.tn.write(password.encode('ascii') + b'\n')
        time.sleep(2)
        # read_very_eager()获取到的是的是上次获取之后本次获取之前的所有输出
        command_result = self.tn.read_very_eager().decode('ascii')
        if 'Login incorrect' not in command_result:
            # print(u'%s 登录成功' % host_ip)
            return True
        else:
            print(u'%s 登录失败,用户名或密码错误' % host_ip)
            return False

    # 此函数实现执行传过来的命令,并输出其执行结果
    def execute_some_command(self, command, waittime):
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(waittime)

        # 获取命令结果
        command_result = self.tn.read_very_eager().decode('ascii')
        ##        print(u'命令执行结果:\n%s' % command_result)
        return command_result

    # 退出telnet
    def logout_host(self):
        self.tn.write(b"exit\n")

class log:
    '''
    功能:写日志,在当前目录Logs文件夹,创建以时间命名,一天一个文件
    '''
    import logging
    # 第一步,创建logger
    logger = logging.getLogger()
    # Log等级总开关
    logger.setLevel(logging.WARNING)

    cur_path = os.path.split(os.path.realpath(__file__))[0]
    logPath = os.path.join(cur_path, 'Logs')
    # 第二步,创建hander,用于写入日志文件
    log_time = time.strftime('%Y%m%d', time.localtime(time.time()))
    log_name = log_time + '.log'
    if not os.path.exists(logPath):
        os.makedirs(logPath)
    logfile = os.path.join(logPath, log_name)
    fh = logging.FileHandler(logfile, mode='a+')
    # 设置输出到file的log等级的开关
    fh.setLevel(logging.WARNING)

    ch = logging.StreamHandler()
    ch.setLevel(logging.WARNING)

    # 第三步 定久handler的输出格式
    # levelname日志级别名称,filename当前很执行程序名,funcName日志当前函数,lineno当前行号,asctime时间,thread线程id,message日志信息
    formatter = logging.Formatter(
        "%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)
    # 第四步 将logger添加到handler里面
    logger.addHandler(fh)
    logger.addHandler(ch)


class UI_Draw(QMainWindow, Ui_MainWindow):

    tableInsert_signal = pyqtSignal(object, object, object)
    cellAlign_signal = pyqtSignal(object, object)
    fresh_datetime_signal = pyqtSignal()

    def __init__(self):
        super(UI_Draw, self).__init__()
        self.setupUi(self)
        self.display_btn_param.clicked.connect(self.display_area_param)
        self.close_all_window_btn.clicked.connect(self.close_all_window)

        self.tableInsert_signal.connect(self.insertToTable)
        self.cellAlign_signal.connect(self.signal_cellAlign)
        self.setWindowTitle('CPU/内存监控')

        self.buttonGroup.buttonClicked.connect(self.handleSelectRunMethod)
        self.delete_line_btn.clicked.connect(self.handleDeleteTableLine)
        self.clear_all_line_btn.clicked.connect(self.handleClearAllTableLine)
        self.select_file_btn.clicked.connect(self.handleSelectFile)
        self.upload_table_btn.clicked.connect(self.handleUploadToTable)
        self.table_init()
        self.result_table.cellPressed.connect(self.table_row_click)


        self.table_dict = {'ip': '0', 'cpu': '1', 'last_cpu': '2', "mem": '3', 'last_mem': '4', 'time': '5'}
        self.table_ip_lists = []
        self.show_cpu = True
        self.show_mem = True
        # 字典用于记录打开窗口,某窗口存在时为激活已存在窗口
        self.subDict = {}



        self.fresh_datetime_signal.connect(self.fresh_datetime)
        self.fresh_btn.clicked.connect(self.thread_start_fresh)
        self.start_draw_btn.clicked.connect(self.start_telnet_datas)
        self.fresh_datetime_signal.emit()

        self.timer = QTimer()
        self.timer.timeout.connect(self.timer_func)
        self.start_draw_btn.clicked.connect(self.timer_start)
        self.start_draw_btn.clicked.connect(self.timer_stop)

        self.timer_date = QTimer()
        self.timer_date.timeout.connect(self.fresh_date_range)
        self.timer_date.start(1000 * 60 * 120)

        self.draw_line_btn.clicked.connect(self.draw_line)
        self.draw_all_window_btn.clicked.connect(self.thread_draw_line_all)
        self.write_ip_csv_btn.clicked.connect(self.write_ip_csv)

    def table_init(self):
        self.result_table.horizontalHeader().setStretchLastSection(True)
        self.result_table.horizontalHeader().setHighlightSections(False)
        # 设置表格为禁止编辑
        self.result_table.horizontalHeader().setFixedHeight(30)
        self.result_table.setFrameShape(QFrame.NoFrame)
        self.result_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.result_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.result_table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.result_table.setSortingEnabled(True)

    def table_row_click(self, row, col):
        self.row_ip = self.result_table.item(row, int(self.table_dict['ip'])).text().strip()
        self.ip_lineEdit.setText(self.row_ip)

    def close_all_window(self):
        for window in self.subDict.keys():
            self.subDict[window].close()
        self.subDict = {}

    def display_area_param(self):
        if self.display_btn_param.text() == '<<':
            self.groupBox_params.setHidden(True)
            self.display_btn_param.setText('>>')
        else:
            self.groupBox_params.setHidden(False)
            self.display_btn_param.setText('<<')

    def searchCellPosition(self, ip):
        totalrows = self.result_table.rowCount()
        if totalrows != 0:
            item = self.result_table.findItems(ip, Qt.MatchExactly)
            row = item[0].row()
            return row
        return -1
      
    def signal_cellAlign(self, row, col):
        # 设置表格单元格对齐方式
        self.result_table.item(row, col).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
       
    def insertToTable(self, row, col, content):
        self.result_table.setCurrentItem(None)
        self.result_table.setItem(int(row), int(col), QTableWidgetItem(content))
        self.cellAlign_signal.emit(int(row), int(col))

    def handleSelectFile(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            '选择你要上传的文件',
            './',
            'csv files(*.csv)'
        )
        if file_path:
            self.file_editline.setEnabled(True)
            self.file_editline.setText(file_path)    
    
    def getfileEditline(self):
        filepath = self.file_editline.text()
        if os.path.exists(filepath):
            return filepath
        else:
            return ''
    
    def countAllValidLine(self):
        total_lines = self.result_table.rowCount()
        self.valid_lines_lbl.setText(str(total_lines))
    
    def handleDeleteTableLine(self):
        if self.result_table.rowCount() == 0:
            return
        currentrow = self.result_table.currentRow()
        if currentrow >= 0:
            row = currentrow
            win_title = self.result_table.item(row, int(self.table_dict['ip'])).text().strip()
        elif currentrow == -1:
            if self.result_table.rowCount() >= 1:
                row = 0
                win_title = self.result_table.item(row, int(self.table_dict['ip'])).text().strip()
        self.result_table.removeRow(row)
        self.delete_dict_key(win_title)
        self.countAllValidLine()

    def delete_dict_key(self, win_title):
        # 删除打开子窗口的字典键关闭窗口
        if win_title in self.subDict.keys():
            if self.subDict[win_title].isVisible() == True:
                self.subDict[win_title].close()
                del self.subDict[win_title]
    
    def handleClearAllTableLine(self):
        self.result_table.clearContents()
        self.result_table.setRowCount(0)
        self.countAllValidLine()
        self.close_all_window()
    
    def setSingleTable(self, content, row=0):
        self.result_table.insertRow(row)
        self.countAllValidLine()
        self.insertToTable(row, 0, content)
        self.cellAlign_signal.emit(row, 0)
    
    def searchDuplicatIP(self, ip):
        # 检查列表中是否已有该IP
        totalrows = self.result_table.rowCount()
        if totalrows != 0:
            for row in range(totalrows):
                try:
                    cell_content = self.result_table.item(row, 0).text().strip()
                except:
                    continue
                if ip == cell_content:
                    print('表格中已有设备%s' % ip)
                    return -1
        return 0

    def handleUploadToTable(self):
        if self.batch_ip_chk.isChecked() == False:
            ip = self.ipValid(self.getip())
            if not ip:
                if ip:
                    print('设备IP为空')
                else:
                    print('%s 非有效IP' % ip)
                return
            # 检查列表中是否已有该IP,如果有就不重复添加了
            if self.searchDuplicatIP(ip):
                return
            self.setSingleTable(ip)
        else:
            # 批量添加ip
            oldrow = self.result_table.rowCount()
            iplists = []
            filepath = self.file_editline.text()
            if filepath:
                if os.path.exists(filepath):
                    iplists = readCsvFile(filepath)
                else:
                    print('%s 文件不存在!' % filepath)
            else:
                print('请先选择文件')
    
            if iplists:
                for row in range(len(iplists)):
                    add_ip = iplists[row]
                    cur_table_row = self.result_table.rowCount()
                    # 检查ip地址是否格式正确
                    if self.ipValid(add_ip):
                        # 检查ip是否已在表格中
                        if int(self.searchDuplicatIP(add_ip)) == -1:
                            continue
                        self.setSingleTable(add_ip, cur_table_row)
                    else:
                        print('%s非有效IP' % add_ip)

    def getip(self):
        return self.input_ip_editline.text().strip()
    
    
    def ipValid(self, ip):
        if re.match(r"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$", ip):
            try:
                if (0 < int(ip.split('.')[0]) <= 233 and 0 <= int(ip.split('.')[1]) <= 255
                        and 0 <= int(ip.split('.')[2]) <= 255 and 0 <= int(ip.split('.')[3]) <= 255):
                    return ip
            except:
                pass
        return
    
    
    def handleSelectRunMethod(self):
        if self.batch_ip_chk.isChecked() == True:
            self.input_ip_editline.setEnabled(False)
            self.select_file_btn.setEnabled(True)
            self.file_editline.setEnabled(True)
        else:
            self.input_ip_editline.setEnabled(True)
            self.select_file_btn.setEnabled(False)
            self.file_editline.setEnabled(False)


    def timer_start(self):
        total_lines = self.result_table.rowCount()
        if total_lines == 0:
            return
        if timer_flag == True:
            self.timer_interval_func()
            self.timer.start(1000 * 60 * int(self.timer_interval_value))

    def timer_stop(self):
        total_lines = self.result_table.rowCount()
        if total_lines == 0:
            return
        if timer_flag == False:
            self.timer.stop()

    def write_ip_csv(self):
        self.get_table_ips()
        file, _ = QFileDialog.getSaveFileName(self, '另存为', './IPList.csv', 'csv files(*.csv)')
        if file:
            with open(file,'w', encoding='utf-8', newline='') as f:
                writer = csv.writer(f)
                for ip in range(len(self.table_ip_lists)):
                    writer.writerow([self.table_ip_lists[ip]])

    def get_table_ips(self):
        # 获取table中的ip
        self.table_ip_lists = []
        total_lines = self.result_table.rowCount()
        if total_lines == 0:
            print('请先在表格中添加设备')
            return 1

        for row in range(total_lines):
            try:
                ip = self.result_table.item(row, 0).text().strip()
                self.table_ip_lists.append(ip)
            except:
                self.insertToTable(row, 0, '')
                continue

    def start_telnet_datas(self):
        global timer_flag
        # 清空上次结果
        total_lines = self.result_table.rowCount()
        if total_lines == 0:
            return

        if self.start_draw_btn.text().strip() == '开始':
            self.start_draw_btn.setText('结束')
            self.clear_all_line_btn.setEnabled(False)
            self.delete_line_btn.setEnabled(False)
            self.upload_table_btn.setEnabled(False)
            self.result_table.setSortingEnabled(False)
            timer_flag = True
            self.timer_interval_comboBox.setEnabled(False)
            for row in range(total_lines):
                self.tableInsert_signal.emit(str(row), self.table_dict['cpu'], '')
                self.tableInsert_signal.emit(str(row), self.table_dict['mem'], '')
                self.tableInsert_signal.emit(str(row), self.table_dict['time'], '')
                self.tableInsert_signal.emit(str(row), self.table_dict['last_cpu'], '')
                self.tableInsert_signal.emit(str(row), self.table_dict['last_mem'], '')
            self.thread_start_draw()
        else:
            self.result_table.setSortingEnabled(False)
            self.start_draw_btn.setText('开始')
            timer_flag = False
            self.timer_interval_comboBox.setEnabled(True)
            self.clear_all_line_btn.setEnabled(True)
            self.delete_line_btn.setEnabled(True)
            self.upload_table_btn.setEnabled(True)

    def thread_start_fresh(self):
        # 刷新表格 和打开的图表窗口
        self.draw_params()
        self.get_table_ips()
        self.t = GetDate()
        self.t.signal_tableInsert_signal.connect(self.insertToTable)
        for i in range(len(self.table_ip_lists)):
            table_row = self.searchCellPosition(self.table_ip_lists[i])
            self.t.get_data(self.table_ip_lists[i], table_row, self.start_time, self.end_time, self.show_cpu, self.show_mem)
        try:
            self.thread_fresh_sub_window()
        except:
            pass

    def thread_fresh_sub_window(self):
        self.draw_params()
        for key in self.subDict.keys():
            self.fresh_sub_window(key, self.subDict[key])

    def create_data_file(self, sheet_name):
        writebook = xlwt.Workbook(data_file)
        sheet = writebook.add_sheet(sheet_name)
        self.write_content(sheet)
        writebook.save(data_file)

    def thread_start_draw(self):
        # 点击开始后执行的函数
        self.get_table_ips()
        self.ipThreads = []

        total_sheet = 0
        if len(self.table_ip_lists) > 0:
            if not os.path.exists(data_file):
                self.create_data_file(self.table_ip_lists[0])
            else:
                readbook = xlrd.open_workbook(data_file)
                for s in readbook.sheet_names():
                    if s not in self.table_ip_lists:
                        total_sheet += 1

                if (total_sheet + int(len(self.table_ip_lists))) > 200:
                    print('超出工作表最大数量')
                    self.create_data_file(self.table_ip_lists[0])

        for i in range(len(self.table_ip_lists)):
            try:
                readbook = xlrd.open_workbook(data_file)

                # 判断工作表是否存在
                if not self.table_ip_lists[i] in readbook.sheet_names():
                    print(f'{self.table_ip_lists[i]}创建')
                    new_readbook = copy(readbook)
                    sheet = new_readbook.add_sheet(self.table_ip_lists[i])
                    self.write_content(sheet)
                    new_readbook.save(data_file)
            except Exception as e:
                print(f'{self.table_ip_lists[i]}工作表访问失败, 错误消息:{e}')

        for i in range(len(self.table_ip_lists)):
            table_row = self.searchCellPosition(self.table_ip_lists[i])
            self.ipthread = Thread(target=self.set_data,
                                   args=(self.table_ip_lists[i], table_row))
            self.ipThreads.append(self.ipthread)
            self.ipthread.start()

    def write_content(self, sheet):
        sheet.write(0, 0, '日期')
        sheet.write(0, 1, 'cpu使用率')
        sheet.write(0, 2, '内存使用率')


    def fresh_datetime(self):
        self.start_dateTimeEdit.setDate(QDate.currentDate())
        self.start_dateTimeEdit.setTime(QTime(00, 00, 00))
        self.end_dateTimeEdit.setDate(QDate.currentDate())
        self.end_dateTimeEdit.setTime(QTime(23, 59, 59))

    def timer_interval_func(self):
        timer_interval = self.timer_interval_comboBox.currentText()
        dict_time = {"2分钟": 2, "5分钟": 5, "10分钟": 10, "30分钟": 2, "1小时": 60, "2小时": 120}
        self.timer_interval_value = dict_time[timer_interval]


    def query_date(self, sheet_name):
        df1 = pd.read_excel(data_file, sheet_name=sheet_name)
        df1 = df1.sort_values(by='日期', ascending=True)
        df1 = df1.set_index('日期', drop=True)
        date_range = df1.index
        if len(date_range) >= 2:
            self.date_range_start = date_range[0][:10]
            self.date_range_end = date_range[len(date_range) - 1][:10]


    def get_data_type_combox(self):
        self.cur_text = self.select_cbox.currentText()
        self.show_cpu = True
        self.show_mem = True
        if self.cur_text == '显示CPU':
            self.show_cpu = True
            self.show_mem = False
        elif self.cur_text == '显示内存':
            self.show_mem = True
            self.show_cpu = False


    def fresh_date_range(self):
        # 功能:为了在新的一天自动
        start_time = datetime.strptime(str(datetime.now().date()) + '0:00', '%Y-%m-%d%H:%M')
        end_time = datetime.strptime(str(datetime.now().date()) + '4:00', '%Y-%m-%d%H:%M')
        now_time = datetime.now()
        # 判断当前时间是否在范围时间内
        if start_time < now_time < end_time:
            self.fresh_datetime_signal.emit()
            self.thread_start_fresh()

    def draw_params(self):
        # 获取数据参数,为传递给子窗口
        self.timer_interval_func()
        self.get_datetime_range()
        self.get_data_type_combox()

    def fresh_sub_window(self, key, win_title):
        try:
            ip = key
            if win_title.isVisible() == True:
                win_title.get_data_params(ip, self.start_time, self.end_time, self.show_cpu, self.show_mem)
                win_title.on_fresh()
        except:
            print(ip, ' 更新出错')

    def get_datetime_range(self):
        self.qdate_start_time = self.start_dateTimeEdit.dateTime()
        self.qdate_end_time = self.end_dateTimeEdit.dateTime()
        self.start_time = self.start_dateTimeEdit.dateTime().toString("yyyy/MM/dd hh:mm")
        self.end_time = self.end_dateTimeEdit.dateTime().toString("yyyy/MM/dd hh:mm")
        # 判断开始时间小于结束时间
        d_start_time = datetime.strptime(self.start_time, "%Y/%m/%d %H:%M")
        d_end_time = datetime.strptime(self.end_time, "%Y/%m/%d %H:%M")

        if d_start_time >= d_end_time:
            self.fresh_datetime_signal.emit()
            self.start_time = self.start_dateTimeEdit.dateTime().toString("yyyy/MM/dd hh:mm")
            self.end_time = self.end_dateTimeEdit.dateTime().toString("yyyy/MM/dd hh:mm")


    def open_sub_window(self, win_title):
        self.ip = win_title
        self.draw_params()
        self.get_datetime_range()

        if win_title in self.subDict.keys():
            try:
                # 子窗口已关闭时
                if self.subDict[win_title].isVisible() == False:
                    del self.subDict[win_title]
                else:
                    self.subDict[win_title].activateWindow()
                    self.subDict[win_title].get_data_params(self.ip, self.qdate_start_time,
                                                            self.qdate_end_time, self.show_cpu, self.show_mem)
                    return
            except:
                pass
        self.sub_window = UI()
        self.sub_window.setWindowTitle('CPU/内存监控 - ' + win_title)
        self.sub_window.get_data_params(self.ip, self.qdate_start_time,
                                        self.qdate_end_time, self.show_cpu, self.show_mem)
        self.sub_window.show()
        self.sub_window.on_fresh()

        self.subDict[win_title] = self.sub_window

    def draw_line(self):
        ip = self.ip_lineEdit.text()
        if len(ip) == 0:
            return
        if not self.ipValid(ip):
            print('%s 非有效IP' % ip)
            return
        self.open_sub_window(ip)

    def thread_draw_line_all(self):
        self.get_table_ips()
        if len(self.table_ip_lists) == 0:
            return
        self.draw_params()
        for i in range(len(self.table_ip_lists)):
            self.open_sub_window(self.table_ip_lists[i])

    def timer_func(self):
        self.get_table_ips()
        if len(self.table_ip_lists) == 0:
            return
        self.thread_start_draw()

    def set_data(self, sheet_name, table_row):
        self.draw_params()
        try:
            cls = GetDate()
            cls.signal_tableInsert_signal.connect(self.insertToTable)
            cls.get_cpu(sheet_name, table_row, self.start_time, self.end_time, self.show_cpu, self.show_mem)
        except:
            pass

    def closeEvent(self, event):
        global timer_flag
        timer_flag = False
        for key in self.subDict.keys():
            self.subDict[key].close()


class GetDate(QObject):

    signal_tableInsert_signal = pyqtSignal(object, object, object)

    def __init__(self):
        super(GetDate, self).__init__()
        self.table_dict = {'ip': '0', 'cpu': '1', 'last_cpu': '2', "mem": '3', 'last_mem': '4', 'time': '5'}


    def get_cpu(self, sheet_name, table_row, qdate_start_time, qdate_end_time, show_cpu, show_mem):
        print(f'1 get_cpu {sheet_name}')
        if self.write_data(sheet_name) == 1:
            return
        self.get_data(sheet_name, table_row, qdate_start_time, qdate_end_time, show_cpu, show_mem)

    def write_data(self, sheet_name):
        print(f'2 write_data {sheet_name}')
        data = ''
        data_mem = ''
        data_list = []
        with lock:
            if timer_flag == False:
                return
            try:
                readbook = xlrd.open_workbook(data_file)
                row = readbook.sheet_by_name(sheet_name).nrows
                new_excel = copy(readbook)
                sheet = new_excel.get_sheet(sheet_name)

            # 为测试,造数据
                time_result = datetime.now().strftime("%Y/%m/%d %H:%M")
                data = random.randint(0, 70)
                data_mem = random.randint(0, 80)
                sheet.write(row, 0, time_result)
                sheet.write(row, 1, data)
                sheet.write(row, 2, data_mem)
                new_excel.save(data_file)

            except Exception as e:
                print('%s get telnet data failed, cpu: %s, mem: %s' % (sheet_name, data, data_mem))
                print('错误信息: ', e)
                return 1


    def get_data(self, sheet_name, table_row, qdate_start_time, qdate_end_time, show_cpu, show_mem):
        print(f'3 get_data {sheet_name}')
        try:
            df = pd.read_excel(data_file, sheet_name=sheet_name)
        except Exception as e:
            print(f'打开{sheet_name}失败')
            return
        if df.shape[0] > 20000:
            df.drop(range(10000), axis=0, inplace=True)
            df.to_excel(data_file, index=False)
        # 数据清洗,缺失值的行要作删除处理,整行为空删除, 日期重复删除,重置索引
        df.dropna(inplace=True)
        df = df.drop_duplicates(['日期'], keep='last').reset_index(drop=True)
        df = df.sort_values(by='日期', ascending=True)
        # 设置日期为索引, 然后获取某个区间数据
        df = df.set_index('日期', drop=True)
        df = df[qdate_start_time:qdate_end_time]
        self.x = df.index

        self.y = df['cpu使用率']
        self.y1 = df['内存使用率']

        if len(self.y) > 0 and len(self.y1) > 0:
            cpu = ''
            last_cpu = ''
            mem = ''
            last_mem = ''
            if show_cpu == True:
                cpu = str(int(self.y.max()))
                last_cpu = str(int(df.values[-1][0]))

            if show_mem  == True:
                mem = str(int(self.y1.max()))
                last_mem = str(int(df.values[-1][1]))

            self.signal_tableInsert_signal.emit(table_row, self.table_dict['cpu'], cpu)
            self.signal_tableInsert_signal.emit(table_row, self.table_dict['last_cpu'], last_cpu)
            self.signal_tableInsert_signal.emit(table_row, self.table_dict['mem'], mem)
            self.signal_tableInsert_signal.emit(table_row, self.table_dict['last_mem'], last_mem)
            self.signal_tableInsert_signal.emit(table_row, self.table_dict['time'], str(df.index[-1]))



if __name__ == '__main__':
    app = QApplication([])
    server = UI_Draw()
    server.show()
    sys.exit(app.exec_())

 

performance.py代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'performance.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1041, 598)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.horizontalLayout_12 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_12.setSpacing(0)
        self.horizontalLayout_12.setObjectName("horizontalLayout_12")
        self.groupBox_table = QtWidgets.QGroupBox(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.groupBox_table.sizePolicy().hasHeightForWidth())
        self.groupBox_table.setSizePolicy(sizePolicy)
        self.groupBox_table.setTitle("")
        self.groupBox_table.setObjectName("groupBox_table")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox_table)
        self.verticalLayout.setObjectName("verticalLayout")
        self.result_table = QtWidgets.QTableWidget(self.groupBox_table)
        self.result_table.setDragEnabled(True)
        self.result_table.setDragDropOverwriteMode(False)
        self.result_table.setAlternatingRowColors(True)
        self.result_table.setShowGrid(False)
        self.result_table.setObjectName("result_table")
        self.result_table.setColumnCount(6)
        self.result_table.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.result_table.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.result_table.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.result_table.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.result_table.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.result_table.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.result_table.setHorizontalHeaderItem(5, item)
        self.result_table.horizontalHeader().setDefaultSectionSize(100)
        self.verticalLayout.addWidget(self.result_table)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setContentsMargins(0, -1, -1, -1)
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.label_4 = QtWidgets.QLabel(self.groupBox_table)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout_7.addWidget(self.label_4)
        self.valid_lines_lbl = QtWidgets.QLabel(self.groupBox_table)
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.valid_lines_lbl.setFont(font)
        self.valid_lines_lbl.setObjectName("valid_lines_lbl")
        self.horizontalLayout_7.addWidget(self.valid_lines_lbl)
        spacerItem = QtWidgets.QSpacerItem(10, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_7.addItem(spacerItem)
        self.clear_all_line_btn = QtWidgets.QPushButton(self.groupBox_table)
        self.clear_all_line_btn.setObjectName("clear_all_line_btn")
        self.horizontalLayout_7.addWidget(self.clear_all_line_btn)
        self.delete_line_btn = QtWidgets.QPushButton(self.groupBox_table)
        self.delete_line_btn.setObjectName("delete_line_btn")
        self.horizontalLayout_7.addWidget(self.delete_line_btn)
        self.write_ip_csv_btn = QtWidgets.QPushButton(self.groupBox_table)
        self.write_ip_csv_btn.setObjectName("write_ip_csv_btn")
        self.horizontalLayout_7.addWidget(self.write_ip_csv_btn)
        self.verticalLayout.addLayout(self.horizontalLayout_7)
        self.verticalLayout_8 = QtWidgets.QVBoxLayout()
        self.verticalLayout_8.setContentsMargins(-1, 10, -1, -1)
        self.verticalLayout_8.setObjectName("verticalLayout_8")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setContentsMargins(-1, 0, -1, 0)
        self.horizontalLayout_5.setSpacing(0)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.label_5 = QtWidgets.QLabel(self.groupBox_table)
        self.label_5.setObjectName("label_5")
        self.horizontalLayout_5.addWidget(self.label_5)
        self.timer_interval_comboBox = QtWidgets.QComboBox(self.groupBox_table)
        self.timer_interval_comboBox.setObjectName("timer_interval_comboBox")
        self.timer_interval_comboBox.addItem("")
        self.timer_interval_comboBox.addItem("")
        self.timer_interval_comboBox.addItem("")
        self.horizontalLayout_5.addWidget(self.timer_interval_comboBox)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_5.addItem(spacerItem1)
        self.start_draw_btn = QtWidgets.QPushButton(self.groupBox_table)
        self.start_draw_btn.setObjectName("start_draw_btn")
        self.horizontalLayout_5.addWidget(self.start_draw_btn)
        self.horizontalLayout_5.setStretch(1, 1)
        self.horizontalLayout_5.setStretch(2, 2)
        self.horizontalLayout_5.setStretch(3, 1)
        self.verticalLayout_8.addLayout(self.horizontalLayout_5)
        self.verticalLayout.addLayout(self.verticalLayout_8)
        self.horizontalLayout_12.addWidget(self.groupBox_table)
        self.groupBox_params = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_params.setTitle("")
        self.groupBox_params.setObjectName("groupBox_params")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox_params)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.groupBox_3 = QtWidgets.QGroupBox(self.groupBox_params)
        self.groupBox_3.setObjectName("groupBox_3")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupBox_3)
        self.verticalLayout_3.setContentsMargins(20, 12, -1, -1)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.single_ip_chk = QtWidgets.QCheckBox(self.groupBox_3)
        self.single_ip_chk.setChecked(True)
        self.single_ip_chk.setAutoExclusive(False)
        self.single_ip_chk.setObjectName("single_ip_chk")
        self.buttonGroup = QtWidgets.QButtonGroup(MainWindow)
        self.buttonGroup.setObjectName("buttonGroup")
        self.buttonGroup.addButton(self.single_ip_chk)
        self.horizontalLayout.addWidget(self.single_ip_chk)
        self.input_ip_editline = QtWidgets.QLineEdit(self.groupBox_3)
        self.input_ip_editline.setObjectName("input_ip_editline")
        self.horizontalLayout.addWidget(self.input_ip_editline)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem2)
        self.horizontalLayout.setStretch(0, 1)
        self.horizontalLayout.setStretch(1, 3)
        self.horizontalLayout.setStretch(2, 2)
        self.verticalLayout_3.addLayout(self.horizontalLayout)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.batch_ip_chk = QtWidgets.QCheckBox(self.groupBox_3)
        self.batch_ip_chk.setAutoExclusive(False)
        self.batch_ip_chk.setObjectName("batch_ip_chk")
        self.buttonGroup.addButton(self.batch_ip_chk)
        self.horizontalLayout_2.addWidget(self.batch_ip_chk)
        self.file_editline = QtWidgets.QLineEdit(self.groupBox_3)
        self.file_editline.setEnabled(False)
        self.file_editline.setReadOnly(True)
        self.file_editline.setObjectName("file_editline")
        self.horizontalLayout_2.addWidget(self.file_editline)
        self.select_file_btn = QtWidgets.QPushButton(self.groupBox_3)
        self.select_file_btn.setEnabled(False)
        self.select_file_btn.setObjectName("select_file_btn")
        self.horizontalLayout_2.addWidget(self.select_file_btn)
        self.horizontalLayout_2.setStretch(0, 1)
        self.horizontalLayout_2.setStretch(1, 2)
        self.horizontalLayout_2.setStretch(2, 1)
        self.verticalLayout_3.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_4.addItem(spacerItem3)
        self.upload_table_btn = QtWidgets.QPushButton(self.groupBox_3)
        self.upload_table_btn.setObjectName("upload_table_btn")
        self.horizontalLayout_4.addWidget(self.upload_table_btn)
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_4.addItem(spacerItem4)
        self.verticalLayout_3.addLayout(self.horizontalLayout_4)
        self.verticalLayout_2.addWidget(self.groupBox_3)
        spacerItem5 = QtWidgets.QSpacerItem(10, 15, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        self.verticalLayout_2.addItem(spacerItem5)
        self.groupBox_5 = QtWidgets.QGroupBox(self.groupBox_params)
        self.groupBox_5.setObjectName("groupBox_5")
        self.verticalLayout_13 = QtWidgets.QVBoxLayout(self.groupBox_5)
        self.verticalLayout_13.setObjectName("verticalLayout_13")
        self.verticalLayout_14 = QtWidgets.QVBoxLayout()
        self.verticalLayout_14.setObjectName("verticalLayout_14")
        self.horizontalLayout_16 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_16.setObjectName("horizontalLayout_16")
        self.label = QtWidgets.QLabel(self.groupBox_5)
        self.label.setObjectName("label")
        self.horizontalLayout_16.addWidget(self.label)
        self.start_dateTimeEdit = QtWidgets.QDateTimeEdit(self.groupBox_5)
        self.start_dateTimeEdit.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.start_dateTimeEdit.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
        self.start_dateTimeEdit.setWrapping(False)
        self.start_dateTimeEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.UpDownArrows)
        self.start_dateTimeEdit.setKeyboardTracking(True)
        self.start_dateTimeEdit.setMaximumDate(QtCore.QDate(9999, 12, 31))
        self.start_dateTimeEdit.setCurrentSection(QtWidgets.QDateTimeEdit.YearSection)
        self.start_dateTimeEdit.setCalendarPopup(True)
        self.start_dateTimeEdit.setTimeSpec(QtCore.Qt.LocalTime)
        self.start_dateTimeEdit.setObjectName("start_dateTimeEdit")
        self.horizontalLayout_16.addWidget(self.start_dateTimeEdit)
        self.label_2 = QtWidgets.QLabel(self.groupBox_5)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_16.addWidget(self.label_2)
        self.end_dateTimeEdit = QtWidgets.QDateTimeEdit(self.groupBox_5)
        self.end_dateTimeEdit.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.end_dateTimeEdit.setTime(QtCore.QTime(23, 59, 59))
        self.end_dateTimeEdit.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(9999, 12, 31), QtCore.QTime(23, 59, 59)))
        self.end_dateTimeEdit.setCurrentSection(QtWidgets.QDateTimeEdit.YearSection)
        self.end_dateTimeEdit.setCalendarPopup(True)
        self.end_dateTimeEdit.setObjectName("end_dateTimeEdit")
        self.horizontalLayout_16.addWidget(self.end_dateTimeEdit)
        spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_16.addItem(spacerItem6)
        self.verticalLayout_14.addLayout(self.horizontalLayout_16)
        self.horizontalLayout_17 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_17.setContentsMargins(-1, 10, -1, 10)
        self.horizontalLayout_17.setObjectName("horizontalLayout_17")
        self.select_cbox = QtWidgets.QComboBox(self.groupBox_5)
        self.select_cbox.setObjectName("select_cbox")
        self.select_cbox.addItem("")
        self.select_cbox.addItem("")
        self.select_cbox.addItem("")
        self.horizontalLayout_17.addWidget(self.select_cbox)
        spacerItem7 = QtWidgets.QSpacerItem(13, 20, QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_17.addItem(spacerItem7)
        self.fresh_btn = QtWidgets.QPushButton(self.groupBox_5)
        self.fresh_btn.setObjectName("fresh_btn")
        self.horizontalLayout_17.addWidget(self.fresh_btn)
        spacerItem8 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_17.addItem(spacerItem8)
        self.horizontalLayout_17.setStretch(0, 1)
        self.horizontalLayout_17.setStretch(1, 2)
        self.verticalLayout_14.addLayout(self.horizontalLayout_17)
        self.horizontalLayout_18 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_18.setObjectName("horizontalLayout_18")
        self.verticalLayout_14.addLayout(self.horizontalLayout_18)
        self.verticalLayout_13.addLayout(self.verticalLayout_14)
        self.verticalLayout_2.addWidget(self.groupBox_5)
        spacerItem9 = QtWidgets.QSpacerItem(1, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        self.verticalLayout_2.addItem(spacerItem9)
        self.groupBox = QtWidgets.QGroupBox(self.groupBox_params)
        self.groupBox.setObjectName("groupBox")
        self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.groupBox)
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.label_3 = QtWidgets.QLabel(self.groupBox)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_3.addWidget(self.label_3)
        self.ip_lineEdit = QtWidgets.QLineEdit(self.groupBox)
        self.ip_lineEdit.setObjectName("ip_lineEdit")
        self.horizontalLayout_3.addWidget(self.ip_lineEdit)
        spacerItem10 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem10)
        self.draw_line_btn = QtWidgets.QPushButton(self.groupBox)
        self.draw_line_btn.setObjectName("draw_line_btn")
        self.horizontalLayout_3.addWidget(self.draw_line_btn)
        self.verticalLayout_6.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setContentsMargins(-1, 10, -1, -1)
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.draw_all_window_btn = QtWidgets.QPushButton(self.groupBox)
        self.draw_all_window_btn.setObjectName("draw_all_window_btn")
        self.horizontalLayout_6.addWidget(self.draw_all_window_btn)
        spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem11)
        self.close_all_window_btn = QtWidgets.QPushButton(self.groupBox)
        self.close_all_window_btn.setObjectName("close_all_window_btn")
        self.horizontalLayout_6.addWidget(self.close_all_window_btn)
        spacerItem12 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem12)
        self.verticalLayout_6.addLayout(self.horizontalLayout_6)
        self.verticalLayout_2.addWidget(self.groupBox)
        spacerItem13 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout_2.addItem(spacerItem13)
        self.horizontalLayout_12.addWidget(self.groupBox_params)
        self.display_btn_param = QtWidgets.QPushButton(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.display_btn_param.sizePolicy().hasHeightForWidth())
        self.display_btn_param.setSizePolicy(sizePolicy)
        self.display_btn_param.setMinimumSize(QtCore.QSize(0, 0))
        self.display_btn_param.setMaximumSize(QtCore.QSize(20, 16777215))
        self.display_btn_param.setAutoRepeatInterval(100)
        self.display_btn_param.setAutoDefault(False)
        self.display_btn_param.setObjectName("display_btn_param")
        self.horizontalLayout_12.addWidget(self.display_btn_param)
        self.horizontalLayout_12.setStretch(0, 8)
        self.horizontalLayout_12.setStretch(1, 2)
        self.verticalLayout_5.addLayout(self.horizontalLayout_12)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1041, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.result_table.setSortingEnabled(False)
        item = self.result_table.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "设备IP"))
        item = self.result_table.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "最高CPU(%)"))
        item = self.result_table.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "当前CPU"))
        item = self.result_table.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "最高内存(%)"))
        item = self.result_table.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", " 当前内存"))
        item = self.result_table.horizontalHeaderItem(5)
        item.setText(_translate("MainWindow", "更新时间"))
        self.label_4.setText(_translate("MainWindow", "共有设备数:"))
        self.valid_lines_lbl.setText(_translate("MainWindow", "0"))
        self.clear_all_line_btn.setText(_translate("MainWindow", "清空表格"))
        self.delete_line_btn.setText(_translate("MainWindow", "删除一行"))
        self.write_ip_csv_btn.setText(_translate("MainWindow", "导出IP"))
        self.label_5.setText(_translate("MainWindow", "更新间隔:"))
        self.timer_interval_comboBox.setItemText(0, _translate("MainWindow", "30分钟"))
        self.timer_interval_comboBox.setItemText(1, _translate("MainWindow", "1小时"))
        self.timer_interval_comboBox.setItemText(2, _translate("MainWindow", "2小时"))
        self.start_draw_btn.setText(_translate("MainWindow", "开始"))
        self.groupBox_3.setTitle(_translate("MainWindow", "设备添加:"))
        self.single_ip_chk.setText(_translate("MainWindow", "添加单台设备"))
        self.input_ip_editline.setText(_translate("MainWindow", "192.168.0.104"))
        self.input_ip_editline.setPlaceholderText(_translate("MainWindow", "请输入设备IP"))
        self.batch_ip_chk.setText(_translate("MainWindow", "批量添加设备"))
        self.select_file_btn.setText(_translate("MainWindow", "选择文件"))
        self.upload_table_btn.setText(_translate("MainWindow", "添加IP到表格"))
        self.groupBox_5.setTitle(_translate("MainWindow", "查询参数:"))
        self.label.setText(_translate("MainWindow", "时间范围:"))
        self.start_dateTimeEdit.setDisplayFormat(_translate("MainWindow", "yyyy/MM/dd HH:mm"))
        self.label_2.setText(_translate("MainWindow", "  -- "))
        self.end_dateTimeEdit.setDisplayFormat(_translate("MainWindow", "yyyy/MM/dd HH:mm"))
        self.select_cbox.setItemText(0, _translate("MainWindow", "全部类型"))
        self.select_cbox.setItemText(1, _translate("MainWindow", "显示CPU"))
        self.select_cbox.setItemText(2, _translate("MainWindow", "显示内存"))
        self.fresh_btn.setText(_translate("MainWindow", "刷新表格/图表"))
        self.groupBox.setTitle(_translate("MainWindow", "窗口操作:"))
        self.label_3.setText(_translate("MainWindow", "IP:"))
        self.draw_line_btn.setText(_translate("MainWindow", "打开画图窗口"))
        self.draw_all_window_btn.setText(_translate("MainWindow", "打开全部画图窗口"))
        self.close_all_window_btn.setText(_translate("MainWindow", "关闭全部画图窗口"))
        self.display_btn_param.setText(_translate("MainWindow", "<<"))

 

sub_window.py代码:

import os
import sys, time
from xlutils.copy import copy
import matplotlib.pyplot as plt
from threading import Thread
plt.style.use('seaborn-whitegrid')
import xlrd
import xlwt
from PyQt5.QtCore import QTimer, pyqtSignal, QDate, QTime
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout)
from matplotlib import dates
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from sub_window_ui import Ui_draw_window
from datetime import datetime
import pandas as pd
import random

data_file = 'datas.xls'
class myFigure(FigureCanvas):
    '''
    画布类,通过Figure创建画布,并且作为参数传递给父类FigureCanvas,最后添加绘图区self.axes
    '''
    # draw_signal = pyqtSignal(object, object)
    def __init__(self, parent=None):
        self.fig = Figure()
        super(myFigure, self).__init__(self.fig)
        # 在父类中激活self.fig,否则不能显示图像
        self.axes = self.fig.add_subplot(111)
        plt.rcParams['font.family'] = 'sans-serif'
        plt.rcParams['font.sans-serif'] = ['Microsoft Yahei']
        self.axes.spines['left'].set_position(('data', 0))

    def show_max_value(self, x, y, tip, color):
        max_b = 0
        cur_a = 0
        for a, b in zip(x, y):
            if int(b) > int(max_b):
                cur_a = a
                max_b = b
        if len(y) > 3:
            cur_a = dates.date2num(datetime.strptime(cur_a, "%Y/%m/%d %H:%M"))
            self.axes.text(cur_a, int(max_b) + 3, '最高%s %.0f' % (tip,int(max_b)), ha='center', va='bottom', fontsize=8,
                           color=color)

    def set_mat_func(self, x, y, y1, show_cpu, show_mem):
        '''
        用清除画布刷新的方法绘图
        :param x: x轴数据
        :param y: y轴数据
        :return:
        '''
        # 数据清洗后,数据类型变成series
        self.x = x.values
        self.y = y.values
        self.y1 = y1.values
        # 清除绘图区
        self.axes.cla()
        self.axes.set_xlabel('日期', fontsize=8)
        self.axes.set_ylabel('CPU/MEM(%)', fontsize=8)
        self.axes.grid(True, linestyle = '--', alpha = 0.5)
        self.axes.xaxis.set_major_formatter(dates.DateFormatter("%Y/%m/%d %H:%M"))
        x = [dates.date2num(datetime.strptime(self.x[i], "%Y/%m/%d %H:%M")) for i in range(len(self.x))]
        # 显示/隐藏数据判断
        if len(self.x) >= 2:
            if show_cpu == True:
                self.axes.plot(x, self.y, 'r-', linewidth=1, marker='.', mfc='w')
                self.show_max_value(self.x, self.y, "CPU", color='r')
            if show_mem == True:
                self.axes.plot(x, self.y1, 'g-', linewidth=1, marker='.', mfc='w')
                self.show_max_value(self.x, self.y1,  "MEM", color='g')
        self.axes.yaxis.set_major_locator(plt.MultipleLocator(20))
        self.axes.set_ylim(-5, 100)
        if len(self.x) <= 1:
            self.axes.set_xticks([])
        self.fig.autofmt_xdate()
        self.fig.subplots_adjust(top=0.92, bottom=0.34)
        self.fig.canvas.draw()
        self.fig.canvas.flush_events()

class UI(QMainWindow, Ui_draw_window):
    draw_signal = pyqtSignal(object, object, object, object, object)
    show_data_signal = pyqtSignal()
    fresh_datetime_signal = pyqtSignal()
    def __init__(self):
        super(UI, self).__init__()
        self.setupUi(self)
        self.resize(640, 400)
        self.fresh_btn.clicked.connect(lambda : Thread(target=self.on_fresh).start())
        self.canvas = myFigure(self.plot_widget)
        self.draw_signal.connect(self.canvas.set_mat_func)
        self.canvas.mpl_connect('motion_notify_event', self.on_motion_notify_event)
        self.show_data_signal.connect(self.show_data)
        self.fresh_datetime_signal.connect(self.fresh_datetime)

        self.x = pd.Series([],dtype=object)
        self.y = pd.Series([], dtype=float)
        self.y1 = pd.Series([], dtype=float)
        self.layout = QVBoxLayout(self.plot_widget)
        self.layout.addWidget(self.canvas)
        self.total_row = 0
        self.ip = ''
        self.show_cpu = True
        self.show_mem = True
        self.init_ui()
        self.timer = QTimer()
        self.timer.timeout.connect(self.on_fresh)
        self.timer.start(1000 * 60 * 10)


    def get_data_params(self, ip, qdate_start_time, qdate_end_time, show_cpu, show_mem):
        self.ip = ip
        self.start_time = qdate_start_time
        self.end_time = qdate_end_time
        self.show_cpu = show_cpu
        self.show_mem = show_mem

        # 设置参数
        if self.show_cpu == True and self.show_mem == True:
            self.select_cbox.setCurrentText('全部类型')
        elif self.show_cpu == True and self.show_mem == False:
            self.select_cbox.setCurrentText('显示CPU')
        elif self.show_cpu == False and self.show_mem == True:
            self.select_cbox.setCurrentText('显示内存')

        self.start_dateTimeEdit.setDateTime(qdate_start_time)
        self.end_dateTimeEdit.setDateTime(qdate_end_time)

    def fresh_datetime(self):
        self.start_dateTimeEdit.setDate(QDate.currentDate())
        self.start_dateTimeEdit.setTime(QTime(00, 00, 00))
        self.end_dateTimeEdit.setDate(QDate.currentDate())
        self.end_dateTimeEdit.setTime(QTime(23, 59, 59))

    def init_ui(self):
        self.fresh_datetime_signal.emit()
        self.xy_data_lbl.setText('数据坐标:\nX:\nY:\n')
        self.draw_signal.emit(self.x, self.y, self.y1, self.show_cpu, self.show_mem)
        self.canvas.fig.suptitle('CPU/内存使用率实时趋势', fontsize=8)
        self.show_data_signal.emit()

    def show_data(self):
        # 显示详细数据信息
        self.date_range_start = ''
        self.date_range_end = ''
        self.query_date()
        if len(self.x) <= 1:
            show_data_num = 0
            self.total_row = 0
        else:
            show_data_num = len(self.x)
            self.total_row -= 1
        self.total_data_lbl.setText('显示数据:%s\n总数据:%s\n开始日期:%s\n结束日期:%s' % (show_data_num, self.total_row,
                                                                   self.date_range_start, self.date_range_end))

    def on_motion_notify_event(self, event):
        '''
        功能:鼠标移动显示数据坐标轴上的x,y值
        :param event:
        :return:
        '''
        if event.xdata == None or event.ydata == None:
            return
        x = dates.num2date(event.xdata).strftime("%Y/%m/%d %H:%M")
        y = event.ydata.astype(int)
        x_values = self.x.values
        y_values = self.y.values
        y1_values = self.y1.values
        str_x = [str(x_values[i]) for i in range(len(x_values))]
        int_y = [y_values[j].astype(int) for j in range(len(y_values))]
        int_y1 = [y1_values[j].astype(int) for j in range(len(y1_values))]
        if x in str_x:
            if y in int_y:
                self.xy_data_lbl.setText('数据坐标:\nX:%s\nY:%s\n' %(x, y))
            elif y in int_y1:
                self.xy_data_lbl.setText('数据坐标:\nX:%s\nY:%s\n' % (x, y))
            else:
                self.xy_data_lbl.setText('数据坐标:\nX:\nY:\n')
        else:
            self.xy_data_lbl.setText('数据坐标:\nX:\nY:\n')

    def on_fresh(self):
        # 刷新图表
        if not self.ip:
            return
        self.sheet_name = self.ip
        if not os.path.exists(data_file):
            return
        readbook = xlrd.open_workbook(data_file)
        # 判断工作表是否存在
        if not self.sheet_name in readbook.sheet_names():
            return
        self.get_data()
        self.draw_signal.emit(self.x, self.y, self.y1, self.show_cpu, self.show_mem)

    def get_file_status(self):
        # 查询数据文件,工作表是否存在
        if not os.path.exists(data_file):
            return
        try:
            readbook = xlrd.open_workbook(data_file)
            # 判断工作表是否存在
            if not self.sheet_name in readbook.sheet_names():
                return
            row = readbook.sheet_by_name(self.sheet_name).nrows
            self.total_row = row
            return 1
        except:
            pass

    def query_date(self):
        # 查询数据的日期范围区间
        if self.get_file_status() != 1:
            return
        df1 = pd.read_excel(data_file, sheet_name=self.sheet_name)
        df1 = df1.sort_values(by='日期', ascending=True)
        df1 = df1.set_index('日期', drop=True)
        date_range = df1.index
        if len(date_range) >= 2:
            self.date_range_start = date_range[0][:10]
            self.date_range_end = date_range[len(date_range) - 1][:10]

    def get_data(self):
        if self.get_file_status() != 1:
            return
        start_time = self.start_dateTimeEdit.dateTime().toString("yyyy/MM/dd hh:mm")
        end_time = self.end_dateTimeEdit.dateTime().toString("yyyy/MM/dd hh:mm")
        # 判断开始时间小于结束时间
        d_start_time = datetime.strptime(start_time,"%Y/%m/%d %H:%M")
        d_end_time = datetime.strptime(end_time,"%Y/%m/%d %H:%M")
        if d_start_time >= d_end_time:
            self.fresh_datetime_signal.emit()
            start_time = self.start_dateTimeEdit.dateTime().toString("yyyy/MM/dd hh:mm")
            end_time = self.end_dateTimeEdit.dateTime().toString("yyyy/MM/dd hh:mm")
        df = pd.read_excel(data_file, sheet_name=self.sheet_name)
        # 数据清洗,缺失值的行要作删除处理,整行为空删除, 日期重复删除,重置索引
        df.dropna(inplace=True)
        df = df.drop_duplicates(['日期'], keep='last').reset_index(drop=True)
        df = df.sort_values(by='日期', ascending=True)
        # 设置日期为索引, 然后获取某个区间数据
        df = df.set_index('日期', drop=True)
        df = df[start_time:end_time]
        self.x = df.index
        self.cur_text = self.select_cbox.currentText()
        self.show_cpu = True
        self.show_mem = True
        if self.cur_text == '显示CPU':
            self.show_cpu = True
            self.show_mem = False
        elif self.cur_text == '显示内存':
            self.show_mem = True
            self.show_cpu = False

        self.y = df['cpu使用率']
        self.y1 = df['内存使用率']
        self.show_data_signal.emit()


if __name__ == '__main__':
    app = QApplication([])
    server = UI()
    server.show()
    sys.exit(app.exec_())

sub_window_ui.py代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'sub_window_ui.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_draw_window(object):
    def setupUi(self, draw_window):
        draw_window.setObjectName("draw_window")
        draw_window.resize(724, 452)
        self.centralwidget = QtWidgets.QWidget(draw_window)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_6.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_6.setSpacing(0)
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.plot_widget = QtWidgets.QWidget(self.centralwidget)
        self.plot_widget.setStyleSheet("")
        self.plot_widget.setObjectName("plot_widget")
        self.verticalLayout.addWidget(self.plot_widget)
        self.verticalLayout_6.addLayout(self.verticalLayout)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setContentsMargins(10, 10, -1, -1)
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_2.setObjectName("groupBox_2")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_2)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.label = QtWidgets.QLabel(self.groupBox_2)
        self.label.setObjectName("label")
        self.horizontalLayout_3.addWidget(self.label)
        self.start_dateTimeEdit = QtWidgets.QDateTimeEdit(self.groupBox_2)
        self.start_dateTimeEdit.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.start_dateTimeEdit.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
        self.start_dateTimeEdit.setWrapping(False)
        self.start_dateTimeEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.UpDownArrows)
        self.start_dateTimeEdit.setKeyboardTracking(True)
        self.start_dateTimeEdit.setMaximumDate(QtCore.QDate(9999, 12, 31))
        self.start_dateTimeEdit.setCurrentSection(QtWidgets.QDateTimeEdit.YearSection)
        self.start_dateTimeEdit.setCalendarPopup(True)
        self.start_dateTimeEdit.setTimeSpec(QtCore.Qt.LocalTime)
        self.start_dateTimeEdit.setObjectName("start_dateTimeEdit")
        self.horizontalLayout_3.addWidget(self.start_dateTimeEdit)
        self.label_2 = QtWidgets.QLabel(self.groupBox_2)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_3.addWidget(self.label_2)
        self.end_dateTimeEdit = QtWidgets.QDateTimeEdit(self.groupBox_2)
        self.end_dateTimeEdit.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.end_dateTimeEdit.setTime(QtCore.QTime(23, 59, 59))
        self.end_dateTimeEdit.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(9999, 12, 31), QtCore.QTime(23, 59, 59)))
        self.end_dateTimeEdit.setCurrentSection(QtWidgets.QDateTimeEdit.YearSection)
        self.end_dateTimeEdit.setCalendarPopup(True)
        self.end_dateTimeEdit.setObjectName("end_dateTimeEdit")
        self.horizontalLayout_3.addWidget(self.end_dateTimeEdit)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem)
        spacerItem1 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem1)
        self.fresh_btn = QtWidgets.QPushButton(self.groupBox_2)
        self.fresh_btn.setObjectName("fresh_btn")
        self.horizontalLayout_3.addWidget(self.fresh_btn)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem2)
        self.verticalLayout_3.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setContentsMargins(-1, 10, -1, 10)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.select_cbox = QtWidgets.QComboBox(self.groupBox_2)
        self.select_cbox.setObjectName("select_cbox")
        self.select_cbox.addItem("")
        self.select_cbox.addItem("")
        self.select_cbox.addItem("")
        self.horizontalLayout_4.addWidget(self.select_cbox)
        spacerItem3 = QtWidgets.QSpacerItem(13, 20, QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_4.addItem(spacerItem3)
        self.horizontalLayout_4.setStretch(0, 1)
        self.horizontalLayout_4.setStretch(1, 2)
        self.verticalLayout_3.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.verticalLayout_3.addLayout(self.horizontalLayout_5)
        self.verticalLayout_5.addLayout(self.verticalLayout_3)
        self.horizontalLayout_7.addWidget(self.groupBox_2)
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setContentsMargins(-1, 9, -1, 9)
        self.horizontalLayout_6.setSpacing(0)
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        spacerItem4 = QtWidgets.QSpacerItem(13, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem4)
        self.total_data_lbl = QtWidgets.QLabel(self.centralwidget)
        self.total_data_lbl.setMinimumSize(QtCore.QSize(120, 40))
        self.total_data_lbl.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.total_data_lbl.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.total_data_lbl.setText("")
        self.total_data_lbl.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
        self.total_data_lbl.setObjectName("total_data_lbl")
        self.horizontalLayout_6.addWidget(self.total_data_lbl)
        spacerItem5 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem5)
        self.xy_data_lbl = QtWidgets.QLabel(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(10)
        sizePolicy.setVerticalStretch(10)
        sizePolicy.setHeightForWidth(self.xy_data_lbl.sizePolicy().hasHeightForWidth())
        self.xy_data_lbl.setSizePolicy(sizePolicy)
        self.xy_data_lbl.setMinimumSize(QtCore.QSize(120, 40))
        self.xy_data_lbl.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.xy_data_lbl.setText("")
        self.xy_data_lbl.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
        self.xy_data_lbl.setObjectName("xy_data_lbl")
        self.horizontalLayout_6.addWidget(self.xy_data_lbl)
        spacerItem6 = QtWidgets.QSpacerItem(10, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem6)
        self.horizontalLayout_7.addLayout(self.horizontalLayout_6)
        self.verticalLayout_6.addLayout(self.horizontalLayout_7)
        self.verticalLayout_6.setStretch(0, 6)
        self.verticalLayout_6.setStretch(1, 1)
        draw_window.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(draw_window)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 724, 23))
        self.menubar.setObjectName("menubar")
        draw_window.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(draw_window)
        self.statusbar.setObjectName("statusbar")
        draw_window.setStatusBar(self.statusbar)

        self.retranslateUi(draw_window)
        QtCore.QMetaObject.connectSlotsByName(draw_window)

    def retranslateUi(self, draw_window):
        _translate = QtCore.QCoreApplication.translate
        draw_window.setWindowTitle(_translate("draw_window", "MainWindow"))
        self.groupBox_2.setTitle(_translate("draw_window", "查询参数:"))
        self.label.setText(_translate("draw_window", "时间范围:"))
        self.start_dateTimeEdit.setDisplayFormat(_translate("draw_window", "yyyy/MM/dd HH:mm"))
        self.label_2.setText(_translate("draw_window", "  -- "))
        self.end_dateTimeEdit.setDisplayFormat(_translate("draw_window", "yyyy/MM/dd HH:mm"))
        self.fresh_btn.setText(_translate("draw_window", "刷新图表"))
        self.select_cbox.setItemText(0, _translate("draw_window", "全部类型"))
        self.select_cbox.setItemText(1, _translate("draw_window", "显示CPU"))
        self.select_cbox.setItemText(2, _translate("draw_window", "显示内存"))