功能:
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", "顯示內存"))
