Step 3:主窗口装配 + QTimer 1s 节拍刷新
← 上一步 Step 2 自绘曲线 · 手册首页 →
Step 3:SystemMonitorWindow 整机装配 + 节拍刷新
目标
把 Step 1 的数据层 + Step 2 的曲线控件,用 SystemMonitorWindow : public QMainWindow 装成整机:中央区两个 QGroupBox(Memory 行:进度条 + label;CPU 行:进度条 + label + 历史曲线),QTimer 每 1s timeout → onTick() 读内存刷进度条、读 CPU% 刷进度条和曲线,无效态显示 N/A + 曲线留缺口。构造时先 cpu_sampler_.sample() 拿基线,第一个 tick 才有有效 CPU%。跑起来是一个能持续刷新的监控窗口。
提示
- 布局怎么搭?
QMainWindow中央放一个QWidget,根QVBoxLayout(contentsMargins(12,12,12,12)+spacing(12))。Memory 分组:QGroupBox("Memory")内QVBoxLayout,一行QHBoxLayout(进度条 stretch=1 + label)。CPU 分组同理,但 VBox 里多加一行CpuHistoryView。底部addStretch(1)顶上去。 - 进度条数值显示在哪?
QProgressBar::setTextVisible(false)——别用进度条自带的百分比文字,另开QLabel显示「75% (12.34 / 16.00 GB)」更直观(内存要显示已用/总量,进度条文字塞不下)。setRange(0,100)+setValue(used_percent)。 - 字节怎么转 GB? 写个
formatGbhelper(匿名 namespace 里):QString::number(bytes / (1024.0*1024.0*1024.0), 'f', 2) + " GB",2 位小数。 - QTimer 怎么装配? 构造里
timer_ = new QTimer(this)、setInterval(1000)(1s,别太短,100ms 会让 CPU% 狂抖不可读)、connect(timeout, onTick)、start()。不开PreciseTimer——系统读取(/proc/Win32)本身有毫秒级耗时,精确定时器无意义还耗能,默认CoarseTimer足够。 - CPU 基线什么时候拿? 构造里、Timer
start()之前调一次cpu_sampler_.sample()——CPU% 要差值,没基线第一拍算不出。start()后立即调一次onTick()先刷内存(CPU% 第一拍差值还没意义,等下个 tick)。 onTick一拍做什么? ①readMemoryStats()→refreshMemory(无效态显示 N/A)②cpu_sampler_.utilization()拿 CPU%——返回 -1 时补一次sample()重建基线(保证下拍能算;utilization 提前返回时不会动 prev_)③refreshCpu(无效态进度条归零 + label N/A + 曲线 push(-1))。- 无效态降级怎么做?
refreshMemory:!s.valid时进度条setValue(0)+ label"N/A"+ return;refreshCpu:percent < 0时进度条归零 + label N/A +cpu_history_->push(-1)(曲线留缺口)+ return。 - ⚠️ CMake 怎么配 Windows 链接?
qt_add_executable+ 链Qt6::Core/Gui/Widgets;if(WIN32) target_link_libraries(... PRIVATE kernel32) endif()——只在 Windows 编译时才链 kernel32(Linux 编译时 Windows 代码被#ifdef剔掉,此链接不触发,不会因找不到 kernel32 报错)。加WIN32_EXECUTABLE ON不弹控制台。
检查点
跑起来(Linux/WSL):窗口标题 CPU / Memory Monitor,Memory 分组进度条随占用变化、label 显示「xx% (xx.xx / xx.xx GB)」,CPU 分组进度条每秒刷新、曲线从左向右铺开滚动,状态栏 Sampling every 1 s。狂跑别的程序看 CPU% 和曲线上升 = 整机通了。断网/改坏路径测试 N/A 降级。⚠️ Windows 路径需实机复验。
QTimer 不熟?先读 QTimer 定时器(进阶看 QTimer 进阶)。 QProgressBar 不熟?先读 QProgressBar。 QMainWindow 装配不熟?先读 QMainWindow 主窗口。 QGroupBox 不熟?先读 QGroupBox。
对照答案
SystemMonitorWindow接口(6 控件指针 + cpu_sampler_ + timer_ + onTick slot):demo/system_monitor_window.h:24-48formatGbhelper(字节→GB 2 位小数):demo/system_monitor_window.cpp:22-25- 构造(装配 + sample 基线 + QTimer 1s + 立即 onTick):
demo/system_monitor_window.cpp:28-46 setupCentral(QVBoxLayout + 两 QGroupBox + 进度条 setTextVisible(false) + 曲线):demo/system_monitor_window.cpp:48-85setupStatusBar:demo/system_monitor_window.cpp:87-90onTick(读内存 + CPU% -1 补 sample + 刷新):demo/system_monitor_window.cpp:92-104refreshMemory(无效态降级 + formatGb label):demo/system_monitor_window.cpp:106-118refreshCpu(无效态降级 + 曲线 push):demo/system_monitor_window.cpp:120-130main(applicationName + show):demo/main.cpp:11-17- CMake(qt_add_executable + if(WIN32) 链 kernel32 + WIN32_EXECUTABLE):
demo/CMakeLists.txt:3-29
搓完了。回 手册首页 看进阶挑战(每核 CPU / 磁盘网络 IO / macOS 支持 / Windows 实机复验),或回 成品导览 对照「怎么读」复盘架构。⚠️ 别忘了 Windows 路径(GlobalMemoryStatusEx / GetSystemTimes)是本成品最大的技术债——代码写好未跑,需 Windows 实机复验后回填文档。