XNSim/XNSysMonitor/mainwindow.cpp
2025-04-28 12:25:20 +08:00

143 lines
4.3 KiB
C++
Executable File

#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "cpuworker.h"
#include <QThread>
#include <QComboBox>
#include <QScrollArea>
#include <QSurfaceFormat>
#include "qcustomplot.h"
#include <unistd.h>
#include <QDebug>
#include <QSet>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 设置窗口标题
setWindowTitle("XNSysMonitor");
setWindowIcon(QIcon(":/icon/XNSysMonitor.png")); // 设置窗口图标
// Set OpenGL format globally
QSurfaceFormat format;
format.setSamples(4); // 4x anti-aliasing
QSurfaceFormat::setDefaultFormat(format);
//获取 CPU 核心数
int numCores = sysconf(_SC_NPROCESSORS_ONLN);
// 创建一个网格布局来放置标签和图表
QGridLayout *layout = new QGridLayout;
// 创建四个图表和下拉框
for (int i = 0; i < 4; ++i) {
QComboBox *comboBox = new QComboBox(this);
for (int j = 0; j < numCores; ++j) {
comboBox->addItem(QString("Core %1").arg(j));
}
// 设置默认选中的核心
comboBox->setCurrentIndex(i);
QCustomPlot *customPlot = new QCustomPlot(this);
customPlot->addGraph();
QPen greenPen(Qt::green);
greenPen.setWidth(2);
customPlot->graph(0)->setPen(greenPen);
customPlot->xAxis->setLabel("Time");
customPlot->yAxis->setLabel("Usage (%)");
customPlot->setBackground(QBrush(QColor("#19232D")));
customPlot->xAxis->setLabelColor(Qt::white);
customPlot->yAxis->setLabelColor(Qt::white);
customPlot->xAxis->setTickLabelColor(Qt::white);
customPlot->yAxis->setTickLabelColor(Qt::white);
customPlot->xAxis->grid()->setVisible(true);
customPlot->yAxis->grid()->setVisible(true);
customPlot->xAxis->setRange(0, 10);
customPlot->yAxis->setRange(0, 0.01); // 初始 Y 轴范围
customPlot->setOpenGl(true); // 启用 OpenGL 模式
customPlot->setMinimumHeight(150); // 设置图表的最小高度
// 将下拉框和图表添加到网格布局中
int row = i / 2; // 行号
int column = i % 2; // 列号
layout->addWidget(comboBox, row * 2, column);
layout->addWidget(customPlot, row * 2 + 1, column);
cpuComboBoxes.append(comboBox);
cpuPlots.append(customPlot);
// 连接下拉框的信号到槽函数
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
[=](int index) {
// 清除图表的旧数据
customPlot->graph(0)->data()->clear();
customPlot->replot();
// 更新已选择的核心
updateCpuUsageForPlot(customPlot, index, 0.0);
});
// 设置初始的 previousIndex 属性
comboBox->setProperty("previousIndex", i);
}
// 创建一个 QWidget 作为滚动区域的内容
QWidget *scrollContent = new QWidget;
scrollContent->setLayout(layout);
// 创建一个 QScrollArea 并设置其内容
QScrollArea *scrollArea = new QScrollArea(this);
scrollArea->setWidget(scrollContent);
scrollArea->setWidgetResizable(true); // 允许滚动区域调整大小
// 将滚动区域设置为主窗口的中心部件
setCentralWidget(scrollArea);
// Create a worker thread
QThread *workerThread = new QThread;
CPUWorker *worker = new CPUWorker;
worker->moveToThread(workerThread);
connect(workerThread, &QThread::started, worker, &CPUWorker::process);
connect(worker, &CPUWorker::dataReady, this, &MainWindow::handleDataReady);
connect(this, &MainWindow::destroyed, workerThread, &QThread::quit);
connect(workerThread, &QThread::finished, worker, &QObject::deleteLater);
workerThread->start();
}
void MainWindow::handleDataReady(int coreIndex, double usage)
{
for (int i = 0; i < cpuComboBoxes.size(); ++i) {
if (cpuComboBoxes[i]->currentIndex() == coreIndex) {
updateCpuUsageForPlot(cpuPlots[i], coreIndex, usage);
}
}
}
void MainWindow::updateCpuUsageForPlot(QCustomPlot *plot, int coreIndex, double usage)
{
// 更新图表数据
plot->graph(0)->addData(plot->graph(0)->dataCount(), usage);
// 限制数据点数量
if (plot->graph(0)->data()->size() > 100) {
plot->graph(0)->data()->removeBefore(plot->graph(0)->dataCount() - 100);
}
// 动态调整 Y 轴范围
double currentMax = plot->yAxis->range().upper;
if (usage > currentMax) {
plot->yAxis->setRange(0, usage * 1.1); // 扩展 Y 轴范围,留出一些空间
}
plot->xAxis->setRange(plot->graph(0)->dataCount() - 100, plot->graph(0)->dataCount());
plot->replot();
}
MainWindow::~MainWindow()
{
delete ui;
}