乐于分享
好东西不私藏

从零到一:用Qt打造企业级《系统监控工具》[附完整源码]

从零到一:用Qt打造企业级《系统监控工具》[附完整源码]

欢迎来到【Qt开发宝典】微信公众号【知识宝库】!

本期《Qt C++工程师》动手实践系列,第051期。本期我们聚焦一个兼具实用性与学习深度的主题——从零到一:用Qt打造企业级《系统监控工具》[附完整源码]本系列文章旨在为关注Qt跨平台开发、Linux C++后端及系统底层架构的开发者,提供一个系统的学习参考。内容将通过原理讲解与实战结合的方式,解析相关核心知识与设计思路,以期对您的技术探索与实践有所裨益。

【技术交流说明】

欢迎关注【Qt开发宝典】微信公众号,定期分享更多Linux C++/Qt等技术干货!

技术交流QQ群:895876809(纯技术讨论群)。入群即构成您对本协议及群规的最终确认。

你是否曾经想过,那些专业的系统监控工具是如何实现的?为什么它们能够实时捕捉系统的每一个细节,并以优雅的方式呈现给用户?

今天,我将带你走进一个真实的项目——内存性能安全卫士(Memory Monitor),一个功能完整、高性能的系统资源监控工具。通过这个项目,你将学到:

  • 🎯如何用Qt构建跨平台应用:一套代码Windows、Linux、macOS三平台无缝运行

  • 📊实时数据可视化的秘诀:波浪动画、图表展示、性能趋势分析

  • 🚨智能告警机制的设计:多级别告警、防频繁触发、系统通知集成

  • 💾数据持久化的最佳实践:SQLite数据库、历史数据查询、CSV导出

  • 🔧系统编程的核心技能:Windows API、Linux /proc、macOS libproc

  • ⚡性能优化的实战经验:帧率控制、内存管理、线程优化

  • 🏆企业级功能的实现:性能基准测试、系统优化建议、健康度评分

一、【工程项目运行】

1. 初始界面
2. Alert
3. Sys

二、【工程项目简介】

【系统监控】

 ✅ 实时内存监控(物理内存 + 交换空间)

 ✅ CPU使用率监控(多核支持)

 ✅ 磁盘使用率监控(多分区支持)

 ✅ 网络速率监控(上行/下行)

 ✅ 进程监控(TOP 10内存/CPU进程)

【数据管理】

 ✅ SQLite数据库集成

 ✅ 历史数据保存(可配置保留天数)

 ✅ 数据查询和统计

 ✅ CSV格式导出

 ✅ 自动数据清理

【告警机制】

 ✅ 5种告警类型(内存、CPU、磁盘、交换空间、网络)

 ✅ 两级告警(警告/严重)

 ✅ 系统通知集成

 ✅ 告警历史记录

 ✅ 防止频繁告警

 ✅ 波浪动画帧率优化(自适应帧率控制)

 ✅ 内存泄漏检查和修复

 ✅ 数据更新优化(只在变化时更新UI)

 ✅ 线程优化(避免UI阻塞)

【配置文件支持】

 ✅ 窗口几何信息保存

 ✅ 主题设置(深浅主题)

 ✅ 更新频率配置

 ✅ 告警阈值配置

 ✅ 数据保留天数设置

 ✅ 语言设置

【历史数据图表】

 ✅ 时间序列图表显示

 ✅ 多指标支持(内存、CPU、磁盘)

 ✅ 时间范围选择

 ✅ 图表导出功能

 ✅ 自动缩放和平移

三、【工程项目】部分源码

1. alertmanager.h
#ifndef ALERTMANAGER_H#define ALERTMANAGER_H#include<QString>#include<QObject>#include<QMap>#include<QVector>#include<QDateTime>#include<QMutex>#include"systeminfo.h"class AlertManager : public QObject {    Q_OBJECTpublic:    enum AlertLevel {        INFO,        WARNING,        CRITICAL    };    enum AlertType {        MEMORY_HIGH,        CPU_HIGH,        DISK_FULL,        SWAP_HIGH,        NETWORK_ANOMALY    };    struct AlertRecord {        QDateTime timestamp;        AlertType type;        AlertLevel level;        QString message;        double value;    };    static AlertManager& instance();    // 设置告警阈值    voidsetThreshold(AlertType type, double warningValue, double criticalValue);    // 检查并触发告警    voidcheckMetrics(const SystemMetrics &metrics);    // 启用/禁用告警    voidsetAlertEnabled(AlertType type, bool enabled);    // 获取告警历史    QVector<AlertRecord> getAlertHistory(int count = 100);    // 清空告警历史    voidclearAlertHistory();    // 获取当前告警状态    QMap<AlertType, boolgetCurrentAlertStates()const;    // 获取告警阈值    QPair<doubledoublegetThreshold(AlertType type)const;signals:    voidalertTriggered(AlertLevel level, const QString &message);    voidalertResolved(AlertType type);private:    AlertManager();    ~AlertManager();    // 禁止拷贝    AlertManager(const AlertManager&) = delete;    AlertManager& operator=(const AlertManager&) = delete;    // 触发告警    voidtriggerAlert(AlertType type, AlertLevel level, const QString &message, double value);    // 解除告警    voidresolveAlert(AlertType type);    // 发送系统通知    voidsendSystemNotification(AlertLevel level, const QString &message);    // 数据成员    QMap<AlertType, QPair<doubledouble>> m_thresholds; // warning, critical    QMap<AlertType, bool> m_alertStates; // 当前告警状态    QMap<AlertType, bool> m_alertEnabled; // 告警是否启用    QVector<AlertRecord> m_alertHistory;    QMutex m_mutex;    // 防止频繁告警的时间戳    QMap<AlertType, QDateTime> m_lastAlertTime;    static const int ALERT_COOLDOWN_SECONDS = 60// 60秒内不重复告警};#endif// ALERTMANAGER_H
2. alertmanager.cpp
#include"alertmanager.h"#include<QMutexLocker>#include<QDebug>#include<QDateTime>#ifdef Q_OS_WIN#include<windows.h>#elif defined(Q_OS_LINUX)#include<QProcess>#elif defined(Q_OS_MAC)#include<QProcess>#endifAlertManager& AlertManager::instance(){    static AlertManager s_instance;    return s_instance;}AlertManager::AlertManager() : QObject(nullptr) {    // 初始化默认阈值    setThreshold(MEMORY_HIGH, 70.085.0);    setThreshold(CPU_HIGH, 70.085.0);    setThreshold(DISK_FULL, 80.090.0);    setThreshold(SWAP_HIGH, 50.075.0);    setThreshold(NETWORK_ANOMALY, 100.0200.0); // MB/s    // 初始化告警状态    m_alertStates[MEMORY_HIGH] = false;    m_alertStates[CPU_HIGH] = false;    m_alertStates[DISK_FULL] = false;    m_alertStates[SWAP_HIGH] = false;    m_alertStates[NETWORK_ANOMALY] = false;    // 初始化告警启用状态    m_alertEnabled[MEMORY_HIGH] = true;    m_alertEnabled[CPU_HIGH] = true;    m_alertEnabled[DISK_FULL] = true;    m_alertEnabled[SWAP_HIGH] = true;    m_alertEnabled[NETWORK_ANOMALY] = false// 默认禁用网络告警}AlertManager::~AlertManager() {}voidAlertManager::setThreshold(AlertType type, double warningValue, double criticalValue){    QMutexLocker locker(&m_mutex);    m_thresholds[type] = qMakePair(warningValue, criticalValue);}voidAlertManager::checkMetrics(const SystemMetrics &metrics){    QMutexLocker locker(&m_mutex);    // 检查内存使用率    if (m_alertEnabled[MEMORY_HIGH]) {        auto threshold = m_thresholds[MEMORY_HIGH];        if (metrics.memoryUsagePercent >= threshold.second) {            triggerAlert(MEMORY_HIGH, CRITICAL,                         QString("内存使用率过高: %1%").arg(metrics.memoryUsagePercent, 0'f'1),                        metrics.memoryUsagePercent);        } else if (metrics.memoryUsagePercent >= threshold.first) {            triggerAlert(MEMORY_HIGH, WARNING,                        QString("内存使用率较高: %1%").arg(metrics.memoryUsagePercent, 0'f'1),                        metrics.memoryUsagePercent);        } else if (m_alertStates[MEMORY_HIGH]) {            resolveAlert(MEMORY_HIGH);        }    }    // 检查CPU使用率    if (m_alertEnabled[CPU_HIGH]) {        auto threshold = m_thresholds[CPU_HIGH];        if (metrics.cpuUsagePercent >= threshold.second) {            triggerAlert(CPU_HIGH, CRITICAL,                        QString("CPU使用率过高: %1%").arg(metrics.cpuUsagePercent, 0'f'1),                        metrics.cpuUsagePercent);        } else if (metrics.cpuUsagePercent >= threshold.first) {            triggerAlert(CPU_HIGH, WARNING,                        QString("CPU使用率较高: %1%").arg(metrics.cpuUsagePercent, 0'f'1),                        metrics.cpuUsagePercent);        } else if (m_alertStates[CPU_HIGH]) {            resolveAlert(CPU_HIGH);        }    }    // 检查磁盘使用率    if (m_alertEnabled[DISK_FULL]) {        auto threshold = m_thresholds[DISK_FULL];        if (metrics.diskUsagePercent >= threshold.second) {            triggerAlert(DISK_FULL, CRITICAL,                        QString("磁盘空间即将满: %1%").arg(metrics.diskUsagePercent, 0'f'1),                        metrics.diskUsagePercent);        } else if (metrics.diskUsagePercent >= threshold.first) {            triggerAlert(DISK_FULL, WARNING,                        QString("磁盘使用率较高: %1%").arg(metrics.diskUsagePercent, 0'f'1),                        metrics.diskUsagePercent);        } else if (m_alertStates[DISK_FULL]) {            resolveAlert(DISK_FULL);        }    }    // 检查交换空间使用率    if (m_alertEnabled[SWAP_HIGH]) {        auto threshold = m_thresholds[SWAP_HIGH];        if (metrics.swapUsagePercent >= threshold.second) {            triggerAlert(SWAP_HIGH, CRITICAL,                        QString("交换空间使用率过高: %1%").arg(metrics.swapUsagePercent, 0'f'1),                        metrics.swapUsagePercent);        } else if (metrics.swapUsagePercent >= threshold.first) {            triggerAlert(SWAP_HIGH, WARNING,                        QString("交换空间使用率较高: %1%").arg(metrics.swapUsagePercent, 0'f'1),                        metrics.swapUsagePercent);        } else if (m_alertStates[SWAP_HIGH]) {            resolveAlert(SWAP_HIGH);        }    }    // 检查网络异常    if (m_alertEnabled[NETWORK_ANOMALY]) {        auto threshold = m_thresholds[NETWORK_ANOMALY];        double maxNetworkSpeed = qMax(metrics.networkSpeedIn, metrics.networkSpeedOut);        if (maxNetworkSpeed >= threshold.second) {            triggerAlert(NETWORK_ANOMALY, CRITICAL,                        QString("网络速率异常: In=%1 KB/s, Out=%2 KB/s")                            .arg(metrics.networkSpeedIn, 0'f'1)                            .arg(metrics.networkSpeedOut, 0'f'1),                        maxNetworkSpeed);        } else if (maxNetworkSpeed >= threshold.first) {            triggerAlert(NETWORK_ANOMALY, WARNING,                        QString("网络速率较高: In=%1 KB/s, Out=%2 KB/s")                            .arg(metrics.networkSpeedIn, 0'f'1)                            .arg(metrics.networkSpeedOut, 0'f'1),                        maxNetworkSpeed);        } else if (m_alertStates[NETWORK_ANOMALY]) {            resolveAlert(NETWORK_ANOMALY);        }    }}voidAlertManager::setAlertEnabled(AlertType type, bool enabled){    QMutexLocker locker(&m_mutex);    m_alertEnabled[type] = enabled;}QVector<AlertManager::AlertRecord> AlertManager::getAlertHistory(int count){    QMutexLocker locker(&m_mutex);    QVector<AlertRecord> result;    int start = qMax(0, m_alertHistory.size() - count);    for (int i = start; i < m_alertHistory.size(); ++i) {        result.append(m_alertHistory[i]);    }    return result;}voidAlertManager::clearAlertHistory(){    QMutexLocker locker(&m_mutex);    m_alertHistory.clear();}QMap<AlertManager::AlertType, boolAlertManager::getCurrentAlertStates()const{    return m_alertStates;}QPair<doubledoubleAlertManager::getThreshold(AlertType type)const{    if (m_thresholds.contains(type)) {        return m_thresholds[type];    }    return qMakePair(0.00.0);}voidAlertManager::triggerAlert(AlertType type, AlertLevel level, const QString &message, double value){    // 检查冷却时间,防止频繁告警    if (m_lastAlertTime.contains(type)) {        QDateTime lastTime = m_lastAlertTime[type];        if (lastTime.secsTo(QDateTime::currentDateTime()) < ALERT_COOLDOWN_SECONDS) {            return// 在冷却期内,不触发告警        }    }    // 如果已经处于告警状态,则不重复触发    if (m_alertStates[type]) {        return;    }    m_alertStates[type] = true;    m_lastAlertTime[type] = QDateTime::currentDateTime();    // 记录告警历史    AlertRecord record;    record.timestamp = QDateTime::currentDateTime();    record.type = type;    record.level = level;    record.message = message;    record.value = value;    m_alertHistory.append(record);    // 限制历史记录数量    if (m_alertHistory.size() > 1000) {        m_alertHistory.removeFirst();    }    qDebug() << "[ALERT]" << message;    // 发送系统通知    sendSystemNotification(level, message);    // 发送信号    emit alertTriggered(level, message);}voidAlertManager::resolveAlert(AlertType type){    if (!m_alertStates[type]) {        return;    }    m_alertStates[type] = false;    QString typeStr;    switch (type) {        case MEMORY_HIGH: typeStr = "内存告警"break;        case CPU_HIGH: typeStr = "CPU告警"break;        case DISK_FULL: typeStr = "磁盘告警"break;        case SWAP_HIGH: typeStr = "交换空间告警"break;        case NETWORK_ANOMALY: typeStr = "网络告警"break;    }    qDebug() << "[ALERT RESOLVED]" << typeStr;    emit alertResolved(type);}voidAlertManager::sendSystemNotification(AlertLevel level, const QString &message){    Q_UNUSED(level);    Q_UNUSED(message);#ifdef Q_OS_WIN    // Windows 系统通知(使用 Windows Toast Notification)    // 简化实现:使用消息框    // 实际应用中可使用 Windows Runtime API#elif defined(Q_OS_LINUX)    // Linux 系统通知(使用 DBus)    QString urgency;    switch (level) {        case INFO: urgency = "low"break;        case WARNING: urgency = "normal"break;        case CRITICAL: urgency = "critical"break;    }    QProcess::startDetached("notify-send"QStringList()         << "-u" << urgency         << "内存监控系统"         << message);#elif defined(Q_OS_MAC)    // macOS 系统通知    QString script = QString(        "display notification \"%1\" with title \"内存监控系统\""    ).arg(message);    QProcess::startDetached("osascript"QStringList() << "-e" << script);#endif}
3. mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include<QMainWindow>#include<QTimer>#include<QLabel>#include<QGridLayout>#include<QProgressBar>#include<QGroupBox>#include<QPushButton>#include<QStyle>#include<QTableWidget>#include"wavewidget.h"#include"systeminfo.h"#include"datamanager.h"#include"alertmanager.h"#include"processmonitor.h"class MainWindow : public QMainWindow{    Q_OBJECTpublic:    MainWindow(QWidget *parent = nullptr);    ~MainWindow();private slots:    voidupdateMemoryUsage();    voidtoggleTheme();    voidshowMemoryInfo();    voidshowSystemInfo();    voidshowSettings();    voidshowProcessList();    voidshowAlertHistory();    voidexportData();    voidonAlertTriggered(AlertManager::AlertLevel level, const QString &message);    voidonAlertResolved(AlertManager::AlertType type);private:    voidsetupUI();    voidsetupConnections();    voidgetMemoryInfo();    voidupdateInfoLabels();    voidupdateProgressBars();    voidupdateSystemMetrics();    voidapplyDarkTheme();    voidapplyLightTheme();    QString formatMemory(qint64 bytes)const;    QString formatSpeed(double kbps)const;    // 内存数据结构    struct MemoryInfo {        qint64 totalPhysical = 0;        qint64 freePhysical = 0;        qint64 usedPhysical = 0;        qint64 totalSwap = 0;        qint64 freeSwap = 0;        qint64 usedSwap = 0;    };    MemoryInfo currentMemory;    SystemMetrics currentMetrics;    QTimer *updateTimer;    // UI 组件    WaveWidget *waveWidget;    QLabel *physicalLabel;    QLabel *swapLabel;    QLabel *totalPhysicalLabel;    QLabel *usedPhysicalLabel;    QLabel *freePhysicalLabel;    QLabel *totalSwapLabel;    QLabel *usedSwapLabel;    QLabel *freeSwapLabel;    QLabel *cpuLabel;    QLabel *diskLabel;    QLabel *networkLabel;    QProgressBar *physicalBar;    QProgressBar *swapBar;    QProgressBar *cpuBar;    QProgressBar *diskBar;    QPushButton *themeButton;    QPushButton *infoButton;    QPushButton *systemButton;    QPushButton *settingsButton;    QPushButton *processButton;    QPushButton *alertButton;    QPushButton *exportButton;    bool darkTheme = true;};#endif// MAINWINDOW_H
4. mainwindow.cpp
#include "mainwindow.h"#include <QApplication>#include <QGridLayout>#include <QGroupBox>#include <QStyleFactory>#include <QStatusBar>#include <QDateTime>#include <QMessageBox>#include <QSysInfo>#include <QVBoxLayout>#include <QHBoxLayout>#include <QFileDialog>#ifdef Q_OS_WIN#include <windows.h>#elif defined(Q_OS_LINUX)#include <sys/sysinfo.h>#endifMainWindow::MainWindow(QWidget *p) : QMainWindow(p), currentMetrics() {    setWindowTitle("Monitor");    resize(1200800);    QApplication::setStyle(QStyleFactory::create("Fusion"));    DataManager::instance().initDatabase();    QWidget *cw = new QWidget(this);    setCentralWidget(cw);    QGridLayout *ml = new QGridLayout(cw);    ml->setSpacing(20);    ml->setContentsMargins(20202020);    waveWidget = new WaveWidget(this);    waveWidget->setMinimumHeight(350);    ml->addWidget(waveWidget, 0012);    QGroupBox *pg = new QGroupBox("Resources", this);    QVBoxLayout *pl = new QVBoxLayout(pg);    physicalBar = new QProgressBar(this);    physicalBar->setRange(0100);    physicalBar->setFormat("Mem: %p%");    physicalBar->setTextVisible(true);    swapBar = new QProgressBar(this);    swapBar->setRange(0100);    swapBar->setFormat("Swap: %p%");    swapBar->setTextVisible(true);    cpuBar = new QProgressBar(this);    cpuBar->setRange(0100);    cpuBar->setFormat("CPU: %p%");    cpuBar->setTextVisible(true);    diskBar = new QProgressBar(this);    diskBar->setRange(0100);    diskBar->setFormat("Disk: %p%");    diskBar->setTextVisible(true);    pl->addWidget(physicalBar);    pl->addWidget(swapBar);    pl->addWidget(cpuBar);    pl->addWidget(diskBar);    ml->addWidget(pg, 10);    QGroupBox *ig = new QGroupBox("Info", this);    QGridLayout *il = new QGridLayout(ig);    totalPhysicalLabel = new QLabel(this);    usedPhysicalLabel = new QLabel(this);    freePhysicalLabel = new QLabel(this);    totalSwapLabel = new QLabel(this);    usedSwapLabel = new QLabel(this);    freeSwapLabel = new QLabel(this);    cpuLabel = new QLabel(this);    diskLabel = new QLabel(this);    networkLabel = new QLabel(this);    il->addWidget(new QLabel("Total:", this), 00);    il->addWidget(totalPhysicalLabel, 01);    il->addWidget(new QLabel("Used:", this), 10);    il->addWidget(usedPhysicalLabel, 11);    il->addWidget(new QLabel("Free:", this), 20);    il->addWidget(freePhysicalLabel, 21);    il->addWidget(new QLabel("Swap:", this), 40);    il->addWidget(totalSwapLabel, 41);    il->addWidget(new QLabel("CPU:", this), 80);    il->addWidget(cpuLabel, 81);    il->addWidget(new QLabel("Disk:", this), 90);    il->addWidget(diskLabel, 91);    il->addWidget(new QLabel("Net:", this), 100);    il->addWidget(networkLabel, 101);    ml->addWidget(ig, 11);    QHBoxLayout *bl = new QHBoxLayout();    themeButton = new QPushButton("Theme", this);    infoButton = new QPushButton("Mem", this);    systemButton = new QPushButton("Sys", this);    processButton = new QPushButton("Proc", this);    alertButton = new QPushButton("Alert", this);    exportButton = new QPushButton("Export", this);    settingsButton = new QPushButton("Set", this);    for(auto btn : {themeButton, infoButton, systemButton, processButton, alertButton, exportButton, settingsButton}) {        btn->setMinimumHeight(35);        bl->addWidget(btn);    }    ml->addLayout(bl, 2012);    applyDarkTheme();    updateTimer = new QTimer(this);    connect(updateTimer, &QTimer::timeout, this, &MainWindow::updateMemoryUsage);    updateTimer->start(1000);    setupConnections();    updateMemoryUsage();    statusBar()->showMessage("OK");}MainWindow::~MainWindow() {    if(updateTimer) {        updateTimer->stop();        delete updateTimer;    }    DataManager::instance().closeDatabase();}void MainWindow::setupConnections() {    connect(themeButton, &QPushButton::clicked, this, &MainWindow::toggleTheme);    connect(infoButton, &QPushButton::clicked, this, &MainWindow::showMemoryInfo);    connect(systemButton, &QPushButton::clicked, this, &MainWindow::showSystemInfo);    connect(processButton, &QPushButton::clicked, this, &MainWindow::showProcessList);    connect(alertButton, &QPushButton::clicked, this, &MainWindow::showAlertHistory);    connect(exportButton, &QPushButton::clicked, this, &MainWindow::exportData);    connect(settingsButton, &QPushButton::clicked, this, &MainWindow::showSettings);    connect(&AlertManager::instance(), QOverload<AlertManager::AlertLevelconst QString&>::of(&AlertManager::alertTriggered),            this, &MainWindow::onAlertTriggered);    connect(&AlertManager::instance(), QOverload<AlertManager::AlertType>::of(&AlertManager::alertResolved),            this, &MainWindow::onAlertResolved);}QString MainWindow::formatMemory(qint64 b) const {    if(b >= 1024*1024*1024return QString("%1G").arg(b / (1024.0*1024*1024), 0'f'1);    if(b >= 1024*1024return QString("%1M").arg(b / (1024.0*1024), 0'f'1);    if(b >= 1024return QString("%1K").arg(b / 1024.00'f'1);    return QString("%1B").arg(b);}QString MainWindow::formatSpeed(double k) const {    if(k >= 1024return QString("%1M/s").arg(k / 1024.00'f'1);    return QString("%1K/s").arg(k, 0'f'1);}void MainWindow::getMemoryInfo() {#ifdef Q_OS_WIN    MEMORYSTATUSEX ms;    ms.dwLength = sizeof(ms);    if(GlobalMemoryStatusEx(&ms)) {        currentMemory.totalPhysical = ms.ullTotalPhys;        currentMemory.freePhysical = ms.ullAvailPhys;        currentMemory.usedPhysical = currentMemory.totalPhysical - currentMemory.freePhysical;        currentMemory.totalSwap = ms.ullTotalPageFile;        currentMemory.freeSwap = ms.ullAvailPageFile;        currentMemory.usedSwap = currentMemory.totalSwap - currentMemory.freeSwap;    }#elif defined(Q_OS_LINUX)    struct sysinfo info;    if(sysinfo(&info) == 0) {        currentMemory.totalPhysical = info.totalram * info.mem_unit;        currentMemory.freePhysical = info.freeram * info.mem_unit;        currentMemory.usedPhysical = currentMemory.totalPhysical - currentMemory.freePhysical;        currentMemory.totalSwap = info.totalswap * info.mem_unit;        currentMemory.freeSwap = info.freeswap * info.mem_unit;        currentMemory.usedSwap = currentMemory.totalSwap - currentMemory.freeSwap;    }#endif}void MainWindow::updateSystemMetrics() {    currentMetrics = SystemMonitor::instance().getCurrentMetrics();}void MainWindow::updateMemoryUsage() {    getMemoryInfo();    updateSystemMetrics();    updateInfoLabels();    updateProgressBars();    DataManager::instance().saveMetrics(currentMetrics);    AlertManager::instance().checkMetrics(currentMetrics);    double pu = currentMemory.totalPhysical > 0 ? (currentMemory.usedPhysical * 100.0 / currentMemory.totalPhysical) : 0;    waveWidget->setMemoryUsage(pu);    statusBar()->showMessage(QDateTime::currentDateTime().toString("hh:mm:ss") + " | Mem:" + QString::number(pu, 'f'1) + "% CPU:" + QString::number(currentMetrics.cpuUsagePercent, 'f'1) + "%");}void MainWindow::updateInfoLabels() {    totalPhysicalLabel->setText(formatMemory(currentMemory.totalPhysical));    usedPhysicalLabel->setText(formatMemory(currentMemory.usedPhysical));    freePhysicalLabel->setText(formatMemory(currentMemory.freePhysical));    totalSwapLabel->setText(formatMemory(currentMemory.totalSwap));    usedSwapLabel->setText(formatMemory(currentMemory.usedSwap));    freeSwapLabel->setText(formatMemory(currentMemory.freeSwap));    cpuLabel->setText(QString::number(currentMetrics.cpuCoreCount));    diskLabel->setText(QString::number(currentMetrics.diskUsagePercent, 'f'1) + "%");    networkLabel->setText(formatSpeed(currentMetrics.networkSpeedIn));}void MainWindow::updateProgressBars() {    int pp = currentMemory.totalPhysical > 0 ? (int)(currentMemory.usedPhysical * 100 / currentMemory.totalPhysical) : 0;    physicalBar->setValue(pp);    int sp = currentMemory.totalSwap > 0 ? (int)(currentMemory.usedSwap * 100 / currentMemory.totalSwap) : 0;    swapBar->setValue(sp);    cpuBar->setValue((int)currentMetrics.cpuUsagePercent);    diskBar->setValue((int)currentMetrics.diskUsagePercent);}void MainWindow::toggleTheme() {    darkTheme ? applyLightTheme() : applyDarkTheme();    darkTheme = !darkTheme;}void MainWindow::showMemoryInfo() {    QMessageBox::information(this, "Mem""Total: " + formatMemory(currentMemory.totalPhysical) + "\nUsed: " + formatMemory(currentMemory.usedPhysical));}void MainWindow::showSystemInfo() {    QMessageBox::information(this, "Sys""OS: " + QSysInfo::prettyProductName() + "\nCores: " + QString::number(currentMetrics.cpuCoreCount));}void MainWindow::showProcessList() {    QVector<ProcessInfo> tp = ProcessMonitor::instance().getTopMemoryProcesses(10);    QString t = "Top 10\n";    for(const auto& p : tp) t += p.name + " " + formatMemory(p.memoryBytes) + "\n";    QMessageBox::information(this, "Proc", t);}void MainWindow::showAlertHistory() {    QVector<AlertManager::AlertRecord> h = AlertManager::instance().getAlertHistory(50);    QString t = "Alerts\n";    for(const auto& r : h) t += r.timestamp.toString("hh:mm:ss") + " " + r.message + "\n";    QMessageBox::information(this, "Alert", t);}void MainWindow::exportData() {    QString fn = QFileDialog::getSaveFileName(this, "Export""""CSV (*.csv)");    if(!fn.isEmpty()) {        QDateTime et = QDateTime::currentDateTime();        DataManager::instance().exportToCSV(fn, et.addDays(-1), et);    }}void MainWindow::showSettings() {    QMessageBox::information(this, "Set""Coming");}void MainWindow::onAlertTriggered(AlertManager::AlertLevel lconst QString &m) {    statusBar()->showMessage((l == AlertManager::CRITICAL ? "CRIT: ""WARN: ") + m);}void MainWindow::onAlertResolved(AlertManager::AlertType t) {    Q_UNUSED(t);    statusBar()->showMessage("OK");}void MainWindow::applyDarkTheme() {    QPalette dp;    dp.setColor(QPalette::WindowQColor(535353));    dp.setColor(QPalette::WindowTextQt::white);    dp.setColor(QPalette::BaseQColor(252525));    dp.setColor(QPalette::ButtonQColor(535353));    dp.setColor(QPalette::ButtonTextQt::white);    dp.setColor(QPalette::HighlightQColor(42130218));    qApp->setPalette(dp);    QString bs = "QPushButton { background-color: #3A3A3A; color: white; border: 1px solid #555; border-radius: 5px; padding: 8px; }";    for(auto btn : {themeButton, infoButton, systemButton, processButton, alertButton, exportButton, settingsButton}) btn->setStyleSheet(bs);    for(QGroupBox *box : findChildren<QGroupBox*>()) box->setStyleSheet("QGroupBox { color: #AAA; border: 2px solid #555; }");    for(QLabel *label : findChildren<QLabel*>()) label->setStyleSheet("QLabel { color: #DDD; }");}void MainWindow::applyLightTheme() {    qApp->setPalette(QApplication::style()->standardPalette());    QString bs = "QPushButton { background-color: #F0F0F0; color: #333; border: 1px solid #AAA; border-radius: 5px; padding: 8px; }";    for(auto btn : {themeButton, infoButton, systemButton, processButton, alertButton, exportButton, settingsButton}) btn->setStyleSheet(bs);    for(QGroupBox *box : findChildren<QGroupBox*>()) box->setStyleSheet("QGroupBox { color: #0066CC; border: 2px solid #AAA; }");    for(QLabel *label : findChildren<QLabel*>()) label->setStyleSheet("QLabel { color: #333; }");}
希望本文能为您的C++/Qt学习之旅提供有价值的参考!欢迎关注【Qt开发宝典】微信公众号,获取更多技术干货。
本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » 从零到一:用Qt打造企业级《系统监控工具》[附完整源码]

猜你喜欢

  • 暂无文章