别光看教程了!用Qt6+CMake亲手打造一个跨平台桌面小工具(附完整源码)
用Qt6+CMake构建跨平台桌面小工具:从零实现系统监控Widget
每次看到教程里那些孤立的代码片段,你是不是总有种"学完就忘"的无力感?今天我们不谈理论,直接动手用Qt6和CMake打造一个真正实用的系统监控工具。这个不足200行代码的小项目,将串联起Widgets编程、信号槽机制、跨平台文件操作等核心知识点,最终生成可在Windows和macOS上运行的独立应用。
1. 环境准备与项目创建
在开始编码前,我们需要配置好开发环境。Qt6的安装比早期版本更加简洁,推荐使用官方在线安装器。安装时注意勾选以下组件:
- Qt 6.5.0 (或最新稳定版)
- CMake 3.24+
- Qt Creator (建议10.0+版本)
- 对应平台的编译工具链
- Windows: MinGW 11.2/MSVC 2019
- macOS: Xcode 14+
创建项目时,打开Qt Creator选择"New Project",在"Application"类别下选择"Qt Widgets Application",关键配置如下:
cmake_minimum_required(VERSION 3.21) project(SystemMonitor LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) find_package(Qt6 REQUIRED COMPONENTS Widgets) add_executable(SystemMonitor main.cpp mainwindow.cpp mainwindow.h resources.qrc ) target_link_libraries(SystemMonitor PRIVATE Qt6::Widgets)提示:现代Qt项目推荐使用CMake而非qmake,因为CMake提供更好的跨平台支持和现代C++特性集成。
2. 核心功能模块实现
2.1 系统信息监控界面设计
我们先创建一个显示CPU、内存使用率的仪表盘界面。在Qt Designer中拖拽以下控件:
- 2个QProgressBar(分别用于CPU和内存)
- 4个QLabel(显示具体数值)
- 1个QPushButton(刷新按钮)
- 1个QTimer(定时刷新数据)
对应的UI文件自动生成的类声明如下:
class Ui_MainWindow { public: QProgressBar *cpuProgress; QProgressBar *memProgress; QLabel *cpuLabel; QLabel *memLabel; QLabel *uptimeLabel; QLabel *diskLabel; QPushButton *refreshButton; void setupUi(QMainWindow *MainWindow) { // 自动生成的布局代码 } };2.2 跨平台系统信息获取
不同操作系统获取系统信息的方式差异很大,我们通过条件编译实现跨平台支持:
#ifdef Q_OS_WIN #include <windows.h> #elif defined(Q_OS_MAC) #include <sys/sysctl.h> #include <mach/mach.h> #endif double getCPUUsage() { static qint64 lastCPU = 0; static qint64 lastSysCPU = 0; #ifdef Q_OS_WIN FILETIME idleTime, kernelTime, userTime; GetSystemTimes(&idleTime, &kernelTime, &userTime); // Windows平台计算逻辑... #elif defined(Q_OS_MAC) host_cpu_load_info_data_t cpuinfo; mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT; host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&cpuinfo, &count); // macOS平台计算逻辑... #endif return usage * 100; }内存信息获取也采用类似方式,关键是要处理好不同平台的数据结构差异。建议将这些功能封装在单独的SystemInfo类中。
3. 数据可视化增强
3.1 实时曲线图绘制
使用QPainter实现简单的历史数据曲线图:
void MonitorWidget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 绘制背景 painter.fillRect(rect(), QColor(240, 240, 240)); // 绘制坐标轴 painter.setPen(QPen(Qt::black, 2)); painter.drawLine(margin, height()-margin, width()-margin, height()-margin); painter.drawLine(margin, margin, margin, height()-margin); // 绘制CPU曲线 painter.setPen(QPen(Qt::red, 2)); for(int i=1; i<cpuHistory.size(); ++i) { painter.drawLine( margin + (i-1)*xStep, height()-margin - cpuHistory[i-1]*yScale, margin + i*xStep, height()-margin - cpuHistory[i]*yScale ); } }3.2 样式美化技巧
现代Qt应用推荐使用QSS(Qt样式表)进行界面美化:
/* resources.qrc中定义的样式 */ QProgressBar { border: 2px solid #3A3A3A; border-radius: 5px; text-align: center; } QProgressBar::chunk { background-color: #5BC8F7; width: 10px; } QLabel#titleLabel { font: bold 16px; color: #333333; }可以通过Qt的资源系统将样式表、图标等打包到可执行文件中,实现真正的跨平台部署。
4. 项目打包与分发
4.1 Windows平台打包
使用windeployqt工具自动收集依赖:
windeployqt --compiler-runtime --no-translations SystemMonitor.exe然后使用NSIS或Inno Setup创建安装程序:
; Inno Setup脚本示例 [Setup] AppName=System Monitor AppVersion=1.0 DefaultDirName={pf}\SystemMonitor OutputDir=output OutputBaseFilename=SystemMonitorSetup [Files] Source: "release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs4.2 macOS应用打包
创建标准的.app bundle:
macdeployqt SystemMonitor.app -dmg这会生成一个包含所有依赖的磁盘映像文件,用户可以直接拖拽安装。
5. 进阶功能扩展
5.1 网络请求集成
使用QNetworkAccessManager添加天气信息显示:
void WeatherWidget::fetchWeather() { QNetworkRequest request(QUrl("https://api.weather.com/v3/...")); QNetworkReply *reply = manager->get(request); connect(reply, &QNetworkReply::finished, [=]() { if(reply->error() == QNetworkReply::NoError) { QJsonDocument doc = QJsonDocument::fromJson(reply->readAll()); QJsonObject obj = doc.object(); // 解析天气数据... } reply->deleteLater(); }); }5.2 数据库存储历史数据
使用SQLite记录监控数据:
bool DataLogger::initDatabase() { db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("monitor.db"); if(!db.open()) return false; QSqlQuery query; query.exec("CREATE TABLE IF NOT EXISTS system_log (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, " "cpu REAL, " "memory REAL)"); return true; }这个看似简单的小工具,实际上已经涵盖了Qt开发的多个核心概念。当你看到自己亲手打造的应用在不同平台上完美运行时,那种成就感是任何教程都给不了的。
