#include "WindowAppTaskMonitorView.h" #include #include "vpControls/VCustomPlot.h" #include "TaskManager.h" #define TABLE_MONITOR_INDEX_INDEX 0 #define TABLE_MONITOR_INDEX_NAME 1 #define TABLE_MONITOR_INDEX_MODE 2 #define TABLE_MONITOR_INDEX_STATUS 3 #define TABLE_MONITOR_INDEX_EXECTIME 4 #define TABLE_MONITOR_INDEX_EXECCOUNT 5 #define TABLE_MONITOR_INDEX_ERRORCOUNT 6 #define TABLE_MONITOR_COLUMN_COUNT 7 #define CPU_NAME "CPU" #define MEMORY_NANE "Memory" #define SYS_TIME_NAME "Time 1S" #ifdef Q_OS_WIN #include "windows.h" #endif #define MB (1024 * 1024) #define KB (1024) WindowAppTaskMonitorView::WindowAppTaskMonitorView(const QString& strTitle, QWidget* parent) : QWidget(parent) , m_pMonitorTable(nullptr) , m_strTitle(strTitle) { ui.setupUi(this); totalNew = idleNew = totalOld = idleOld = 0; cpuPercent = 0; memoryPercent = 0; memoryAll = 0; memoryUse = 0; m_nCustomPlotKey = 0; m_nCustomPlotSysTemKey = 0; //执行命令获取 process = new QProcess(this); connect(process, SIGNAL(readyRead()), this, SLOT(slotReadData())); // 初始化监控表格 this->initMonitorTable(); // 初始化曲线 this->initMonitorCustomPlot(); // UI元素初始化 this->initUI(); } WindowAppTaskMonitorView::~WindowAppTaskMonitorView() { } /// /// UI元素初始化 /// void WindowAppTaskMonitorView::initUI() { ui.comboBox->addItem(SYS_TIME_NAME); ui.splitter->setStretchFactor(0, 10); ui.splitter->setStretchFactor(1, 2); // 初始化系统定时器 m_eventTimer.setInterval(1000); connect(&m_eventTimer, SIGNAL(timeout()), this, SLOT(onCustomPlotTimer())); connect(ui.splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(slotSplitterMoved(int, int))); m_eventTimer.start(); } /// /// 初始化监控表格 /// void WindowAppTaskMonitorView::initMonitorTable() { // 创建变量表格 m_pMonitorTable = new QTableWidget(ui.tabMonitor); // 列数 m_pMonitorTable->setColumnCount(TABLE_MONITOR_COLUMN_COUNT); // 设置表头文字 QStringList headers; headers << ("Index") << ("Name") << ("Mode") << ("Status") << ("Run Time(ms)") << ("Run Count") << ("Error Count"); m_pMonitorTable->setHorizontalHeaderLabels(headers); //设置表头字体 QFont font = m_pMonitorTable->horizontalHeader()->font(); font.setBold(true); m_pMonitorTable->horizontalHeader()->setFont(font); // 设置文字左对齐 m_pMonitorTable->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter); // 设置为不可编辑 m_pMonitorTable->setEditTriggers(QAbstractItemView::NoEditTriggers); // 设置为整行选中模式 m_pMonitorTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_pMonitorTable->setSelectionMode(QAbstractItemView::SingleSelection); // 设置最左侧的序号不用显示 m_pMonitorTable->verticalHeader()->setVisible(false); //设置行高 m_pMonitorTable->verticalHeader()->setDefaultSectionSize(10); //点击表时不对表头行光亮(获取焦点) m_pMonitorTable->horizontalHeader()->setHighlightSections(false); } void WindowAppTaskMonitorView::initMonitorCustomPlot() { const QPoint newPt(0, 0); const QSize newSize(0, 0); m_pCustomPlotTask = new VCustomPlot(nullptr, newPt, newSize); QHBoxLayout* Tasklayout = new QHBoxLayout(); Tasklayout->setContentsMargins(0, 0, 0, 0); Tasklayout->setSpacing(0); Tasklayout->addWidget(m_pCustomPlotTask); ui.curveMonitor->setLayout(Tasklayout); m_pCustomPlotTask->setBgColor(qRgb(70, 70, 70)); //隐藏表格线 m_pCustomPlotTask->getPlot()->xAxis->grid()->setVisible(false); //m_pCustomPlotTask->getPlot()->yAxis->grid()->setVisible(false); //初始化跟随鼠标游标 m_pCustomPlotTask->initTracer(); //初始化指示器数据高亮及悬停提示等 m_pCustomPlotTask->initItem(); m_pCustomPlotTask->initUI("", "Task Exec Time (ms)"); // 设置为可缩放可拖动模式 m_pCustomPlotTask->setInteractions(3); m_pCustomPlotTask->setRangeX(0, 200, 200); m_pCustomPlotTask->setRangeY(0, 1000, 5); ////////////////////////////////////////////////////////////////////////// m_pCustomPlotSystem = new VCustomPlot(nullptr, newPt, newSize); QHBoxLayout* layoutSystem = new QHBoxLayout(); layoutSystem->setContentsMargins(0, 0, 0, 0); layoutSystem->setSpacing(0); layoutSystem->addWidget(m_pCustomPlotSystem); ui.curveSystem->setLayout(layoutSystem); m_pCustomPlotSystem->setBgColor(qRgb(70, 70, 70)); //隐藏表格线 m_pCustomPlotSystem->getPlot()->xAxis->grid()->setVisible(false); //m_pCustomPlotTask->getPlot()->yAxis->grid()->setVisible(false); //初始化跟随鼠标游标 m_pCustomPlotSystem->initTracer(); //初始化指示器数据高亮及悬停提示等 m_pCustomPlotSystem->initItem(); m_pCustomPlotSystem->addGraph(CPU_NAME, qRgb(31, 128, 186), 1, true); m_pCustomPlotSystem->addGraph(MEMORY_NANE, qRgb(32, 184, 141), 1, true); m_pCustomPlotSystem->initUI("", "System (%)"); //设置拖动缩放模式 m_pCustomPlotSystem->setInteractions(0); m_pCustomPlotSystem->setRangeX(0, 200, 200); m_pCustomPlotSystem->setRangeY(0, 100, 5); } /// /// 调整大小的消息中改变表格栏的宽度 /// /// void WindowAppTaskMonitorView::resizeEvent(QResizeEvent* event) { Q_UNUSED(event); // qDebug() << "WindowAppVariableTable::resizeEvent"; int nTotalSize = m_pMonitorTable->size().width(); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_INDEX, nTotalSize * 0.05); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_NAME, nTotalSize * 0.2); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_MODE, nTotalSize * 0.2); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_STATUS, nTotalSize * 0.1); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_EXECTIME, nTotalSize * 0.15); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_EXECCOUNT, nTotalSize * 0.15); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_ERRORCOUNT, nTotalSize * 0.15); m_pMonitorTable->resize(ui.tabMonitor->size()); } /// /// /// /// /// void WindowAppTaskMonitorView::slotSplitterMoved(int pos, int index) { Q_UNUSED(pos); Q_UNUSED(index); QList list = ui.splitter->sizes(); if (m_pCustomPlotTask) { m_pCustomPlotTask->resize(ui.curveMonitor->size()); } if (m_pCustomPlotSystem) { m_pCustomPlotSystem->resize(ui.curveMonitor->size()); } m_pMonitorTable->resize(ui.tabMonitor->size()); } /// /// 定时器Even事件 /// void WindowAppTaskMonitorView::onCustomPlotTimer() { QString strName = ui.comboBox->currentText(); if (strName == SYS_TIME_NAME) { //m_nCustomPlotKey++; // 刷新显示 if (!m_pCustomPlotTask->isHidden() ) { m_pCustomPlotTask->replot(); } } // 只有在资源监视窗口打开的情况下,才刷新资源的曲线图 if (!m_pCustomPlotSystem->isHidden()) { getCPU(); getMemory(); cpuPercent = (cpuPercent < 0 ? 0 : cpuPercent); cpuPercent = (cpuPercent > 100 ? 0 : cpuPercent); if (m_pCustomPlotSystem) { m_pCustomPlotSystem->addValve(MEMORY_NANE, (double)m_nCustomPlotSysTemKey, (double)memoryPercent); if (cpuPercent < 100) { m_pCustomPlotSystem->addValve(CPU_NAME, (double)m_nCustomPlotSysTemKey, (double)cpuPercent); } m_nCustomPlotSysTemKey++; if (!m_pCustomPlotSystem->isHidden()) { m_pCustomPlotSystem->replot(); } } } } /// /// 添加一行新的Task信息 /// /// void WindowAppTaskMonitorView::addNewTask(const TASK* pTask) { int nCount = m_pMonitorTable->rowCount(); this->m_pMonitorTable->setRowCount(nCount + 1); // 填充Task表格,并且保存每一个需要更新的数据表格 QVector pNewItems; QTableWidgetItem* newItem = new QTableWidgetItem(QString::number(nCount + 1)); m_pMonitorTable->setItem(nCount, TABLE_MONITOR_INDEX_INDEX, newItem); pNewItems.push_back(newItem); newItem = new QTableWidgetItem(pTask->strName); m_pMonitorTable->setItem(nCount, TABLE_MONITOR_INDEX_NAME, newItem); pNewItems.push_back(newItem); newItem = new QTableWidgetItem(pTask->strModeName); m_pMonitorTable->setItem(nCount, TABLE_MONITOR_INDEX_MODE, newItem); pNewItems.push_back(newItem); newItem = new QTableWidgetItem(emExecStatus.key((short)pTask->execParams.nStatus)); m_pMonitorTable->setItem(nCount, TABLE_MONITOR_INDEX_STATUS, newItem); pNewItems.push_back(newItem); newItem = new QTableWidgetItem(QString::number(pTask->execParams.nExecTime)); m_pMonitorTable->setItem(nCount, TABLE_MONITOR_INDEX_EXECTIME, newItem); pNewItems.push_back(newItem); newItem = new QTableWidgetItem(QString::number(pTask->execParams.nExecCount)); m_pMonitorTable->setItem(nCount, TABLE_MONITOR_INDEX_EXECCOUNT, newItem); pNewItems.push_back(newItem); newItem = new QTableWidgetItem(QString::number(pTask->execParams.nErrorCount)); m_pMonitorTable->setItem(nCount, TABLE_MONITOR_INDEX_ERRORCOUNT, newItem); pNewItems.push_back(newItem); for (int i = 0; i < TABLE_MONITOR_COLUMN_COUNT; i++) { m_pMonitorTable->item(nCount, i)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); } // 保存Task的名字和每一个表格单元的指针 m_TaskTableWidgetItems.insert(pTask->strName, pNewItems); // 将Task 的名字存如下拉控件中 ui.comboBox->addItem(pTask->strName); QVector m_defaultColors; m_defaultColors << QColor(0, 176, 180) << QColor(255, 192, 0) << QColor(0, 113, 193) << QColor(72, 103, 149) << QColor(185, 87, 86) << QColor(0, 177, 125) << QColor(214, 77, 84) << QColor(71, 164, 233) << QColor(34, 163, 169) << QColor(40, 45, 48) << QColor(162, 121, 197) << QColor(72, 202, 245) << QColor(0, 150, 121) << QColor(111, 9, 176) << QColor(250, 170, 20); // 防止取颜色超出预设表 if (nCount > m_defaultColors.size()) { nCount = 0; } // 创建曲线 m_pCustomPlotTask->addGraph(pTask->strName, m_defaultColors.at(nCount)); } /// /// 删除一个Task信息 /// /// void WindowAppTaskMonitorView::delTask(const QString& strTaskName) { int nRow = m_allTaskNames.indexOf(strTaskName); m_pMonitorTable->removeRow(nRow); m_pCustomPlotTask->delGraph(strTaskName); } /// /// 更新Task信息 /// /// void WindowAppTaskMonitorView::updateTask(const TASK* pTask) { const QVector& pTaskItems = m_TaskTableWidgetItems.value(pTask->strName); const TASK_PARAMS& params = pTask->execParams; // 根据Task的执行状态更新这个表格对应的数据 pTaskItems[TABLE_MONITOR_INDEX_STATUS]->setText(emExecStatus.key((short)pTask->execParams.nStatus)); pTaskItems[TABLE_MONITOR_INDEX_EXECTIME]->setText( QString::number(params.nExecTime) + " (" + QString::number(1000.0 / (params.nExecTime+ 0.0001), 'f', 1) + "fps)"); pTaskItems[TABLE_MONITOR_INDEX_EXECCOUNT]->setText(QString::number(params.nExecCount)); pTaskItems[TABLE_MONITOR_INDEX_ERRORCOUNT]->setText("Error( " + QString::number(params.nErrorCount) +") TimtOut("+ QString::number(params.nTriggerFailedCount) + ")"); // this->m_pMonitorTable->viewport()->update(); m_pCustomPlotTask->addValve(pTask->strName, (double)m_nCustomPlotKey, (double)params.nExecTime); m_nCustomPlotKey++; // 当选择了该Task 后,该Task 执行曲线刷新动作 QString strName = ui.comboBox->currentText(); if (strName == pTask->strName) { if (!m_pCustomPlotTask->isHidden()) { m_pCustomPlotTask->replot(QCustomPlot::rpQueuedReplot); } } } /// /// 更新Task的Mode参数 /// /// void WindowAppTaskMonitorView::updateTaskMode(const TASK* pTask) { const QVector& pTaskItems = m_TaskTableWidgetItems.value(pTask->strName); pTaskItems[TABLE_MONITOR_INDEX_MODE]->setText(pTask->strModeName); } /// /// 更新Task的状态参数 /// /// void WindowAppTaskMonitorView::updateTaskStatus(const TASK* pTask) { const QVector& pTaskItems = m_TaskTableWidgetItems.value(pTask->strName); const TASK_PARAMS& params = pTask->execParams; pTaskItems[TABLE_MONITOR_INDEX_STATUS]->setText(emExecStatus.key((short)params.nStatus)); } /// /// 更新Task的配置参数 /// /// void WindowAppTaskMonitorView::updateTaskOption(const TASK* pTask) { const QVector& pTaskItems = m_TaskTableWidgetItems.value(pTask->strName); // const TASK_PARAMS& params = pTask->execParams; pTaskItems[TABLE_MONITOR_INDEX_MODE]->setText(pTask->strModeName); // pTaskItems[TABLE_MONITOR_INDEX_PRIORITY]->setText(emPriority.key((short)params.nPriority)); // pTaskItems[TABLE_MONITOR_INDEX_TASKINTERV]->setText(QString::number(params.nPostDelay)); } /// /// /// void WindowAppTaskMonitorView::getCPU() { #ifdef Q_OS_WIN static FILETIME preidleTime; static FILETIME prekernelTime; static FILETIME preuserTime; FILETIME idleTime; FILETIME kernelTime; FILETIME userTime; GetSystemTimes(&idleTime, &kernelTime, &userTime); quint64 a, b; quint64 idle, kernel, user; a = (preidleTime.dwHighDateTime << 31) | preidleTime.dwLowDateTime; b = (idleTime.dwHighDateTime << 31) | idleTime.dwLowDateTime; idle = b - a; a = (prekernelTime.dwHighDateTime << 31) | prekernelTime.dwLowDateTime; b = (kernelTime.dwHighDateTime << 31) | kernelTime.dwLowDateTime; kernel = b - a; a = (preuserTime.dwHighDateTime << 31) | preuserTime.dwLowDateTime; b = (userTime.dwHighDateTime << 31) | userTime.dwLowDateTime; user = b - a; if ((kernel + user) == 0) { return; } cpuPercent = (kernel + user - idle + 0.0001) * 100 / (kernel + user + 0.0001); preidleTime = idleTime; prekernelTime = kernelTime; preuserTime = userTime; #else if (process->state() == QProcess::NotRunning) { totalNew = idleNew = 0; process->start("cat /proc/stat"); } #endif } /// /// /// void WindowAppTaskMonitorView::getMemory() { #ifdef Q_OS_WIN MEMORYSTATUSEX statex; statex.dwLength = sizeof(statex); GlobalMemoryStatusEx(&statex); memoryPercent = statex.dwMemoryLoad; memoryAll = statex.ullTotalPhys / MB; memoryFree = statex.ullAvailPhys / MB; memoryUse = memoryAll - memoryFree; #else if (process->state() == QProcess::NotRunning) { process->start("cat /proc/meminfo"); } #endif } /// /// /// void WindowAppTaskMonitorView::slotReadData() { while (!process->atEnd()) { QString s = QLatin1String(process->readLine()); if (s.startsWith("cpu")) { QStringList list = s.split(" "); idleNew = list.at(5).toUInt(); foreach(QString value, list) { totalNew += value.toUInt(); } quint64 total = totalNew - totalOld; quint64 idle = idleNew - idleOld; cpuPercent = 100 * (total - idle) / total; totalOld = totalNew; idleOld = idleNew; break; } else if (s.startsWith("MemTotal")) { s.replace(" ", ""); s = s.split(":").at(1); memoryAll = s.left(s.length() - 3).toUInt() / KB; } else if (s.startsWith("MemFree")) { s.replace(" ", ""); s = s.split(":").at(1); memoryFree = s.left(s.length() - 3).toUInt() / KB; } else if (s.startsWith("Buffers")) { s.replace(" ", ""); s = s.split(":").at(1); memoryFree += s.left(s.length() - 3).toUInt() / KB; } else if (s.startsWith("Cached")) { s.replace(" ", ""); s = s.split(":").at(1); memoryFree += s.left(s.length() - 3).toUInt() / KB; memoryUse = memoryAll - memoryFree; memoryPercent = 100 * memoryUse / memoryAll; break; } } } void WindowAppTaskMonitorView::showEvent(QShowEvent* event) { Q_UNUSED(event); // qDebug() << "WindowAppVariableTable::resizeEvent"; int nTotalSize = m_pMonitorTable->size().width(); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_INDEX, nTotalSize * 0.05); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_NAME, nTotalSize * 0.2); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_MODE, nTotalSize * 0.2); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_STATUS, nTotalSize * 0.1); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_EXECTIME, nTotalSize * 0.15); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_EXECCOUNT, nTotalSize * 0.15); m_pMonitorTable->setColumnWidth(TABLE_MONITOR_INDEX_ERRORCOUNT, nTotalSize * 0.15); m_pMonitorTable->resize(ui.tabMonitor->size()); } void WindowAppTaskMonitorView::changeEvent(QEvent* event) { Q_UNUSED(event); if (this->m_pMonitorTable != nullptr) { this->m_pMonitorTable->update(); } }