ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

C++ Qt开发Windows实时系统监控工具:从API采集到图表展示

C++ Qt开发Windows实时系统监控工具:从API采集到图表展示 如果你已经在 Windows 上用 C 写过一些控制台程序接下来想往真正的桌面工具和系统编程方向走一步那就非常值得自己实现一个 Windows 实时系统监控工具。这类项目正好能同时把 Windows API、系统信息采集、多线程刷新、GUI 图表绘制和工程组织这些点都串起来而且做出来之后每天打开电脑都愿意用是一个非常适合当“第一个工程项目”的练手项目。这次的文章不是单纯介绍轮子而是直接围绕“C Qt 写一个 Windows 实时系统监控工具”这整条技术路线展开。会先给核心能力速览再讲环境准备、系统编程知识结构、基于 Windows API 的数据采集方案、Qt 界面实时刷新与图表绘制、进程管理、批量导出日志以及常见问题排查和工程化建议。如果你想找一个小而完整、能放上简历、又能持续扩展的系统编程项目这篇可以直接收藏。1. 核心能力速览能力项说明项目类型Windows 桌面实时系统监控工具主要技术栈C17 / C20、Qt Widgets、Qt Charts、Windows SDK API核心功能CPU 使用率、内存占用、磁盘空间、网络流量、进程列表、系统信息展示可视化方式实时折线图、仪表盘或数字卡片、进程表格、状态栏数据刷新方式QTimer 定时器配合实时采集线程常见刷新间隔 1s 或 2s扩展能力可导出历史数据到 CSV、可按 CPU/内存排序进程列表、可后台托盘运行后端采集GetSystemTimes、GlobalMemoryStatusEx、GetDiskFreeSpaceEx、CreateToolhelp32Snapshot 等支持平台Windows 10 / Windows 11严格说跟随 Qt 与 MSVC 编译器支持范围启动方式命令行直接运行qmake/CMake 构建后生成独立 exe是否支持 API可自行封装本地 HTTP 或进程间通信接口按需扩展是否支持批量任务可批量导出监控记录或对进程列表做批量排序筛选适合人群想进阶系统编程的 C 初学者、Qt 桌面开发新手、需要一台 Windows 机器做日常监控的开发者从技术分量来看这个项目并不难但它覆盖的知识面足够广。对比纯写一个计算器或者一个窗口程序监控工具至少要处理“数据怎么来、界面怎么刷、采集和 UI 怎么不卡顿、数据量大了怎么办”这类问题。这些问题正是系统编程和桌面工程的核心。2. 适用场景与使用边界这个项目适合这些场景自己电脑日常性能监控快速判断 CPU 或内存是否被某个进程占满。学习 Windows 系统编程练习 Win32 API 和 Qt 的线程模型。做课程设计、毕业设计或者简历项目功能扩展空间大。作为团队内网工具在开发机上统一查看系统资源占用。后续扩展为远程监控客户端把本机数据上报到服务端。不适合的场景要做全功能进程管理器请直接用任务管理器不必重复造轮子。要做专业性能分析工具应该用 Process Explorer、PerfView 等成熟工具。需要跨平台监控 macOS/Linux需要重新设计采集层Windows 特性和 Qt 行为不完全一致。需要监控系统内部驱动层面数据超出用户态 API 的范畴。使用边界必须说明这个工具应该只采集本机资源信息不要采集用户输入、浏览器历史、文件内容等隐私数据。如果你的工具后续要上报到服务器或做成服务端监控必须明确告知使用者采集了哪些数据并确保数据合法合规。涉及公司内部机器监控时需要取得业务方和管理员授权。不要把系统监控工具做成隐蔽的“探针”这是安全底线。3. 环境准备与 Qt 开发环境搭建一套干净的开发环境能省掉后面大部分排查时间。下面给出通用步骤具体版本以你本机为准。3.1 安装 Qt从 Qt 官网下载在线安装器或者使用镜像地址。安装时组件建议组件是否建议说明Qt 6.x / Qt 5.15建议选用长期支持版本功能稳定第三方库兼容性好MSVC 2022 或 MinGW 编译器必须选一个Qt 的 kit 编译需要编译器Qt Charts如果要用折线图则必须勾选本文功能演示基于图表展示Qt Debug 和 Release 库建议都安装调试和发布都需要CMake 和 Qt Creator建议安装Qt Creator 友好度高CMake 是主流构建方式如果你之前已经装了 Qt 但没勾 Charts可以在安装器中“添加或移除组件”补上 Qt Charts不需要重装整套环境。3.2 安装编译器与构建工具如果选 MSVC 编译需要安装 Visual Studio Build Tools至少包含“使用 C 的桌面开发”组件。MSVC 编译包体积比较大但对 Windows API 的支持最完整所以本项目优先选择 MSVC。如果选 MinGW也要注意 Qt 的 MinGW 版本和编译器位数必须一致。Qt 6 对 MinGW 的支持虽然成熟但个别第三方库仍然需要自行编译。3.3 验证 Qt 环境安装结束后建议先创建一个最简单的 Qt Widgets 空白窗口编译运行一次确认 kit 配置正常#include QApplication #include QLabel int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label(Qt is running); label.resize(320, 120); label.show(); return app.exec(); }编译通过且显示窗口说明 Qt 和编译器的连接没问题。这个步骤是后续所有调试的基础。如果这一步都报错先回去检查 kit、编译器路径和组件版本不要急着写监控逻辑。3.4 项目目录结构建议建议按下面这种结构组织工程避免所有代码堆在 main.cpp 里SystemMonitor/ ├── CMakeLists.txt ├── src/ │ ├── main.cpp │ ├── MainWindow.h │ ├── MainWindow.cpp │ ├── SysInfoCollector.h │ ├── SysInfoCollector.cpp │ ├── CpuMonitorWidget.h │ ├── CpuMonitorWidget.cpp │ ├── MemoryMonitorWidget.h │ └── MemoryMonitorWidget.cpp ├── ui/ │ └── mainwindow.ui └── resources/ └── app.rc数据采集、UI 展示、业务逻辑分开后面加网络监控、磁盘监控、日志导出都不会乱。4. 系统监控工具的核心知识Windows 系统编程怎么入门很多 C 初学者写 Qt 项目时只写界面一接触到系统监控就不知道数据从哪里取。实际上Windows 系统编程入门并不难常用 API 很固定。4.1 用户态可用的系统信息 API系统编程不是要求你深入内核用户态能拿到的信息比想象中多数据类型推荐 API说明CPU 总体使用率GetSystemTimes获取 idle、kernel、user 时间计算两次采样的变化量当前进程 CPU 占用GetProcessTimes配合 OpenProcess 获取指定进程 CPU 时间内存总量/可用/使用率GlobalMemoryStatusExMEMORYSTATUSEX 结构体包含 ullTotalPhys、ullAvailPhys、dwMemoryLoad磁盘总容量/剩余空间GetDiskFreeSpaceEx以盘符为单位获取 totalBytes、freeBytes进程列表CreateToolhelp32Snapshot获取进程快照配合 PROCESSENTRY32 遍历进程名、PID、父进程 PID系统启动时间GetTickCount64返回自系统启动以来经过的时间网络流量数据GetIfTable / GetIfEntry2按网络接口获取字节数也可以组合 PDH 计数器这些 API 都是 Windows SDK 自带不需要第三方库。对系统监控工具来说绝大多数数据都来自用户态基本不涉及驱动开发。4.2 CPU 使用率的关键思路CPU 使用率不是拿一次采样就能算出来的必须在两个时间点分别采集然后计算增量。推荐做法是在采集线程里维护上一组 FILETIME间隔 1 秒后再次采样再算差值。核心逻辑可以用下面的伪代码概括double getCpuUsagePercent() { FILETIME idleTime, kernelTime, userTime; GetSystemTimes(idleTime, kernelTime, userTime); uint64_t idle fileTimeToUint64(idleTime); uint64_t kernel fileTimeToUint64(kernelTime); uint64_t user fileTimeToUint64(userTime); uint64_t total kernel user; if (isFirstSample) { prevIdle idle; prevKernel kernel; prevUser user; isFirstSample false; return 0.0; } uint64_t idleDelta idle - prevIdle; uint64_t totalDelta total - (prevKernel prevUser); prevIdle idle; prevKernel kernel; prevUser user; if (totalDelta 0) return 0.0; return (1.0 - static_castdouble(idleDelta) / totalDelta) * 100.0; }注意几点首次采样直接返回 0不要参与图表显示。kernel 时间已经包含了 idle 时间计算 total 时可以直接用 kernel user。如果使用高精度计时器注意单位统一建议统一转换为 uint64 纳秒或直接保留 FILETIME 的 100ns 单位。4.3 内存和磁盘数据的获取内存使用率的获取在 Windows 上非常稳定MEMORYSTATUSEX memInfo; memInfo.dwLength sizeof(memInfo); GlobalMemoryStatusEx(memInfo); // 总物理内存 quint64 totalMemory memInfo.ullTotalPhys; // 可用物理内存 quint64 availableMemory memInfo.ullAvailPhys; // 使用百分比 DWORD memoryLoadPercent memInfo.dwMemoryLoad;磁盘数据可以遍历盘符获取ULARGE_INTEGER totalBytes, freeBytes, availableToCaller; GetDiskFreeSpaceExA(C:\\, availableToCaller, totalBytes, freeBytes); // 剩余空间 quint64 freeSpace freeBytes.QuadPart; // 总空间 quint64 totalSpace totalBytes.QuadPart; // 使用率 double diskUsage (totalSpace 0) ? 0.0 : (1.0 - static_castdouble(freeSpace) / totalSpace) * 100.0;如果显示中文路径或盘符建议使用宽字符版本 API避免编码问题。4.4 进程列表数据进程列表通常用快照方式获取HANDLE snapshot CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot INVALID_HANDLE_VALUE) return; PROCESSENTRY32 entry; entry.dwSize sizeof(PROCESSENTRY32); if (Process32First(snapshot, entry)) { do { // QString name QString::fromWCharArray(entry.szExeFile); // DWORD pid entry.th32ProcessID; // DWORD parentPid entry.th32ParentProcessID; } while (Process32Next(snapshot, entry)); } CloseHandle(snapshot);如果还想显示每个进程的 CPU 占用率需要再调用 OpenProcess GetProcessTimes并且同样要做两次采样计算差值。进程数量多的时候这个操作开销不小建议放到子线程中执行不要在 UI 线程里遍历。5. 实时刷新机制不要在 UI 线程里直接采集Qt 界面开发中最常见的问题就是“界面卡住”。很多人用一个 while 循环读取系统数据然后在循环里直接更新界面效果就是窗口无法拖动、图表变成幻灯片。解决办法是把数据采集放到独立线程或者至少用 QTimer 分时调度。5.1 推荐刷新架构采集线程不停收集系统数据然后通过信号把数据发送给主线程主线程只负责更新界面。这样即使采集线程阻塞几百毫秒界面也不会卡死。可以使用 QThread 配合信号槽class SysInfoCollector : public QThread { Q_OBJECT public: explicit SysInfoCollector(QObject *parent nullptr); void stopCollecting(); signals: void systemInfoReady(const SystemInfoSnapshot snapshot); protected: void run() override; private: std::atomicbool m_running{true}; };在 run 里循环采集当 stop 被调用或被析构时退出void SysInfoCollector::run() { while (m_running.load()) { SystemInfoSnapshot snapshot; snapshot.cpuUsage getCpuUsagePercent(); snapshot.memoryUsage getMemoryUsagePercent(); snapshot.totalMemory getTotalMemory(); snapshot.freeMemory getFreeMemory(); snapshot.processList getProcessList(); emit systemInfoReady(snapshot); QThread::msleep(1000); } }主线程中接收信号后更新 QChart、QTableView、QLabel 等控件。5.2 用 QTimer 驱动图表刷新也可以不使用独立线程只用 QTimer 周期触发采集和刷新。区别是采集过程不能耗时太长否则会阻塞 UI。对于只会做基础学习的场景下面这种写法更简单QTimer *timer new QTimer(this); connect(timer, QTimer::timeout, this, MainWindow::refreshSystemInfo); timer-start(1000);refreshSystemInfo 里先调用采集函数再更新图表。这种方式对 CPU、内存、磁盘监控足够但如果要遍历几百个进程并计算每个进程的 CPU建议还是走线程方案。5.3 为什么推荐结合线程和计时器监控工具的实际瓶颈往往在进程列表的 CPU 占用计算。进程数多时OpenProcess 可能失败也可能因为权限不足拿不到某些系统进程信息这些都可能拖慢采集。把采集放到线程里会稳很多。更稳妥的做法是采集线程负责所有 API 调用主线程只接收整理好的 structUI 控件收到数据后一次刷新。6. Qt Charts 绘图与实时曲线展示实时监控工具如果没有图表可读性会差很多。下面以 Qt Charts 的 QChart QLineSeries 为例演示如何绘制 CPU 使用率曲线。6.1 在界面中创建 QChartView首先在 MainWindow 的构造函数里初始化图表QLineSeries *cpuSeries new QLineSeries(); cpuSeries-setName(CPU); QChart *chart new QChart(); chart-addSeries(cpuSeries); chart-createDefaultAxes(); chart-axisX()-setTitleText(时间); chart-axisY()-setRange(0, 100); chart-axisY()-setTitleText(使用率 %); chart-legend()-setVisible(true); QChartView *chartView new QChartView(chart); chartView-setRenderHint(QPainter::Antialiasing); setCentralWidget(chartView);6.2 更新曲线数据在刷新函数中把最新 CPU 使用率追加到 series 尾部同时保留最近 N 个点。为了避免曲线无限延长我会维护一个计数并移除最老的点static int pointIndex 0; const int maxPointCount 120; qreal x pointIndex; qreal y snapshot.cpuUsage; cpuSeries-append(x, y); if (cpuSeries-count() maxPointCount) { cpuSeries-remove(0); } pointIndex;如果你希望 X 轴对应真实时间戳可以把 QDateTime::currentMSecsSinceEpoch 作为 X 值再配合 QDateTimeAxis 展示时间。注意大量时间戳会出现 X 轴范围变化需要手动调整 chart-axisX()-setRange。6.3 多个指标组合展示同样的方式可以组合 CPU、内存、磁盘使用率三条曲线。绘制多个 series 前建议确认 Y 轴单位一致如果不一致就需要双 Y 轴或者拆成多个 chart view。监控工具中CPU 和内存都使用“百分比”作为 Y 轴可以共用一个 Y 轴网络流量建议单独画在另一个 Tab 中。6.4 避免图表性能问题图表数据点不是越多越好。如果你每秒刷一个点长期运行一天就是 86400 个点Qt Charts 绘制耗时明显上升。推荐只保留最近 60300 个点或者用历史数据文件保存完整记录界面上只显示滚动窗口。这样兼顾了实时性和性能。7. 进程管理功能与批量操作7.1 进程列表表格使用 QTableView QAbstractTableModel 来展示进程列表数据模型可以设计为class ProcessListModel : public QAbstractTableModel { Q_OBJECT public: enum Column { Name, Pid, ParentPid, MemoryMB, CpuUsage, ColumnCount }; int rowCount(const QModelIndex parent QModelIndex()) const override; int columnCount(const QModelIndex parent QModelIndex()) const override; QVariant data(const QModelIndex index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: QVectorProcessInfo m_processList; };每次收到系统快照时先用新的进程列表替换旧数据void ProcessListModel::updateProcessList(const QVectorProcessInfo newList) { beginResetModel(); m_processList newList; endResetModel(); }这种方式简单直接频繁刷新时会重建整个表格CPU 占用会稍高但胜在代码清晰。如果进程数量很大且刷新频率高于 1s可以改成增量更新。7.2 按列排序和筛选QTableView 开启排序模式只需要ui-processTable-setSortingEnabled(true);再通过自定义 model 的 lessThan 逻辑即可。按 CPU 占用排序最实用能一眼看出是哪个进程占满了机器。7.3 导出监控快照为 CSV系统监控工具很容易加上“导出记录”功能方便后续分析。CSV 写入可以使用标准文件流void saveSnapshotToCsv(const QString path, const QVectorSystemInfoSnapshot snapshots) { QFile file(path); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qWarning() Open file failed: file.errorString(); return; } QTextStream out(file); out timestamp,cpu_usage,memory_usage,total_memory_mb,free_memory_mb\n; for (const auto snap : snapshots) { out snap.timestamp.toString(Qt::ISODate) , snap.cpuUsage , snap.memoryUsage , snap.totalMemory / (1024 * 1024) , snap.freeMemory / (1024 * 1024) \n; } }如果你的工具要批量导出长时间的数据建议追加写入而不是每次重新打开文件。文件句柄频繁开关会影响性能还可能导致数据丢失。7.4 进程操作的安全边界很多教程喜欢加“结束进程”按钮用 TerminateProcess 杀进程。从学习角度这很直观但从安全角度我不建议默认开启该功能尤其是给别人用的工具。杀错系统进程可能导致系统不稳定对没有授权的机器而言也不合规。如果要做至少加双重确认并过滤系统关键进程。合理的设计是进程列表只做展示和排序不做杀进程操作或者仅提供“查看进程路径”“打开所在目录”这类无害操作。8. 界面细节与系统集成8.1 托盘运行监控工具应当能最小化到系统托盘避免长期挂在任务栏占位置。可以用 QSystemTrayIconQSystemTrayIcon *trayIcon new QSystemTrayIcon(this); trayIcon-setIcon(style()-standardIcon(QStyle::SP_ComputerIcon)); trayIcon-setToolTip(System Monitor); QMenu *trayMenu new QMenu(this); trayMenu-addAction(显示主窗口, this, MainWindow::showMainWindow); trayMenu-addAction(退出, this, MainWindow::quitApplication); trayIcon-setContextMenu(trayMenu); trayIcon-show();注意托盘运行也要在退出时清理线程资源并防止重复实例。8.2 开机自启如果工具要常驻后台可以考虑开机自启。最简单的实现是写注册表 Run 键QSettings settings(HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run, QSettings::NativeFormat); settings.setValue(SystemMonitor, QDir::toNativeSeparators(QCoreApplication::applicationFilePath()));取消自启则删除该键。这里要提醒自启动功能默认不要开启最好放在设置界面里让用户自行选择避免被打上“流氓软件”标签。8.3 权限提升的代价直接双击运行的普通进程权限有限某些进程信息会读取失败。如果提升到管理员权限运行确实能拿到更多系统数据但会给用户带来 UAC 弹窗也不适合作为常驻工具。更合理的取舍是“普通权限运行 忽略权限不足的进程”尽量不要为此改动 manifest 强行要求管理员权限。9. 资源占用与性能观察这个项目的资源占用主要来自三部分采集线程调用 Windows API 的频率。进程列表的数量和字段数量。Qt Charts 图表刷新时的绘制耗时。9.1 刷新频率的影响刷新间隔从 1 秒改为 0.5 秒图表会看起来更“流畅”但采集和绘制总耗时可能成倍增加。实际项目中1 秒刷新足够观察 CPU、内存、磁盘变化。如果要做进程级监控建议独立设置刷新频率比如进程表 2 秒刷一次而主图表 1 秒刷一次。9.2 显存与内存占用监控工具不涉及 GPU 推理一般没有显存压力。Qt 程序的内存占用主要来自界面控件和数据缓冲。长期运行时如果历史数据点无限制添加内存会持续增长。所以前面提到限制最大点数、定时清理历史快照都是很实际的内存优化手段。如果后续加入网络流量统计需要维护接口累计字节数同样不能无上限增长。建议每间隔一段时间把统计数据导出并清空内存缓冲。9.3 如何判断采集线程是否拖累系统可以在工具中额外显示“上次采集耗时”如果耗时超过 500ms说明采集逻辑太重或进程权限问题导致阻塞。这个指标很直观也能帮你在开发时快速发现性能问题。10. 常见问题与排查方法问题现象可能原因排查方式解决方案Qt Charts 头文件找不到安装 Qt 时未勾选 Charts 模块检查 include 路径和 CMake 是否链接 Qt6Charts在 Qt 安装器中补装 Charts 组件编译报 link 错误找不到 Windows API未链接 user32.lib、kernel32.lib 等系统库查看 linker 输出确认缺失符号在 CMake 中添加对应库或使用 Qt 的 WinMain 入口程序启动后窗口可以显示但没有数据采集线程未启动或 QTimer 未 start检查构造函数是否执行 start在 MainWindow 构造函数中启动线程或计时器CPU 使用率一直显示 0首次采样逻辑错误或两次采样时间差太小检查前后采样的时间戳差值确保采样间隔至少在 300ms 以上进程列表部分进程显示不了普通权限运行系统进程读取受限确认是否需要查看系统级进程保持普通权限不强行提升权限内存持续增长图表数据点无限增加或 QTableView 频繁 reset查看任务管理器内存趋势限制 series 点数、改用增量更新关闭窗口后进程还在后台未设置退出口逻辑窗口关闭只隐藏检查 closeEvent在 closeEvent 中确认退出并终止采集线程开机自启后打不开窗口Run 键指向路径或工作目录不对查看注册表键值和程序路径使用绝对路径并在启动时设置工作目录CSV 导出大文件卡住在主线程里执行文件 IO查看任务管理器 UI 是否无响应将文件写入放到后台线程或者限制导出数据量编译相关的问题是最常见的。很多初学者把“Qt 编译不过”直接归因于代码错误其实绝大多数是先检查安装组件、编译器、CMake 配置。使用 Qt Creator 打开项目时一定要确认右侧 kit 选择的编译器和 Qt 版本一致。11. 最佳实践与工程化建议11.1 先跑通最小闭环第一次开发建议分两个阶段。第一阶段不做图表不做进程列表只做一个窗口里面放一个 QLabel每隔 1 秒显示一次 CPU 使用率。先把“采集数据 → 刷 UI”的闭环打通。第二阶段再逐步加图表、内存、磁盘、进程列表。这样每一步出了问题都能快速定位。11.2 保留可复用的采集模块把系统信息采集封装成独立类可以方便以后迁移到其他工具里。比如你后面写一个 C 网络监控程序同样可以直接复用 SysInfoCollector 的 CPU 和内存采集逻辑。建议所有 Windows API 调用都集中在采集类内部不让 UI 层直接出现 Win32 类型。11.3 数据结构和日志先行系统的数据快照建议用统一的 struct 定义struct SystemInfoSnapshot { QDateTime timestamp; double cpuUsage; double memoryUsage; quint64 totalMemory; quint64 freeMemory; quint64 totalDiskSpace; quint64 freeDiskSpace; QVectorProcessInfo processList; }; struct ProcessInfo { QString name; quint32 pid; quint32 parentPid; quint64 memoryBytes; double cpuUsage; };这样无论是 UI 更新、CSV 导出还是网络上报都是在同一个结构体上操作。数据类型统一后批量任务也更容易实现。11.4 发布与部署Qt 程序交付给别的机器时需要把依赖的 DLL 一起打包。可用 windeployqt 自动收集 Qt 依赖库windeployqt SystemMonitor.exe执行完成后检查 Output 目录下的 Qt6Core.dll、Qt6Gui.dll、Qt6Widgets.dll 等文件是否存在。如果使用了 Charts还需要确保 Qt6Charts.dll 被正确复制。发布版本建议使用 Release 模式编译不要带上调试符号和庞大的 debug 库。如果目标机是 Windows 10/11 的干净系统还需要注意 Microsoft Visual C Redistributable。如果程序是静态链接或已带上运行库则不需要额外安装建议发布前用虚拟机验证。11.5 合规与安全注意事项始终回顾三点监控工具只能使用在你自己拥有或已获授权的设备上。不得把监控模块悄悄嵌入到别人的软件里更不能用于员工监控、用户行为追踪等未经授权的场景。导出日志时不要包含 PID 之外的其他敏感信息比如进程对应的命令行参数可能导致隐私泄露普通监控工具默认不要搜集完整命令行。工具发布出去后如果被滥用成了兜售的“监控软件”本质上已经违背了系统编程工具的正当用途所以代码里要有明确的免责声明并默认关闭敏感数据采集。12. 总结与下一步这个 Windows 实时系统监控工具是典型的小而完整的系统编程项目。它不要求高深的算法也不依赖重型框架但通过它你能把 C、Qt、Windows API、线程、图表、发布部署这套桌面开发链路完整走一遍。做完这个项目之后你至少能回答这些高频技术问题如何获取 CPU 使用率、如何遍历进程、如何让 UI 不卡顿、如何用 Qt Charts 画实时曲线、如何发布 Qt 程序。最先要验证的功能是 CPU 使用率采集。只要这个闭环跑通后面加内存、磁盘、网络都是同类套路。最容易踩的坑有两个第一Qt 安装时漏掉 Charts 组件第二在 UI 线程直接采集导致窗口卡死。后续可以继续扩展的方向有很多把监控数据保存到 SQLite做历史趋势分析通过 HTTP 接口把本机数据上报到服务端变成远程监控客户端接入 QSS 美化界面增加网络速率监控增加启动项管理和服务状态查看。这样一来同一个项目就可以从“练手工程”一直演进成一套可用的系统运维工具。如果你正在学 C 和 Qt这个项目非常建议现在就开始跟着上面章节一步一步做完成度会远超预期。
返回列表