Qt Charts太丑还受限?我写了一套纯QML暗黑主题图表组件库
Qt Charts太丑还受限?我写了一套纯QML暗黑主题图表组件库
9种图表 × 6套暗黑主题 × 纯QML原生 × MIT协议,一文讲透 QML 数据可视化的"第三条路"
前言:QML开发者的数据可视化之痛
做QML桌面开发的,几乎都踩过这几个坑:
Qt Charts 的三座大山:
- GPL v3 授权——商业闭源项目?要么买 Qt Commercial License,要么另找出路
- 默认样式"工业风"——出来的图表一股 Qt Demo 味儿,放到暗黑主题界面里直接劝退
- 定制成本高——想改个圆角柱状图、渐变饼图、带中心数值的环形图?底层全是 C++ 对象,QML侧能改的属性有限
第三方方案?
| 方案 | 问题 |
|---|---|
| QCustomPlot | C++ Widget体系,和QML不搭 |
| pyqtgraph | Python生态,QML项目没法用 |
| ECharts/QWebChannel | 嵌Web引擎,包体积暴增,性能打折 |
| 自己手写 Canvas | 能写,但每次都要重新造轮子 |
我自己在做一套暗黑风格的 QML Dashboard 时,被这个问题折磨了好几周。最后干脆自己写了一套——StyledCharts。
StyledCharts 是什么
一句话:面向 QML 开发者的暗黑主题原生图表组件库。
| 特性 | 说明 |
|---|---|
| 图表种类 | 折线图、柱状图、饼图、环形图、面积图、仪表盘、迷你折线图、雷达图、散点图(共9种) |
| 主题系统 | 6套暗黑主题,一键切换,颜色/字体/间距统一管控 |
| 技术栈 | 纯 QML 实现,混合渲染(QML Canvas + Qt Quick Shapes) |
| 授权 | MIT 协议,商业项目随意用 |
| 依赖 | 不依赖 Qt Charts 模块,无 GPL 风险 |
核心设计理念:和 Qt Style Pack 共享同一套 ThemeManager 主题系统。如果你已经在用 Style Pack 的 UI 组件,图表组件会自动继承同一套暗黑主题,整个 Dashboard 的视觉语言完全统一。
技术架构:为什么不用 Qt Charts?
先回答一个很多人会问的问题:为什么不基于 Qt Charts 包一层?
Qt Charts 的问题不只是"丑": ├── 商业授权 GPL v3 → 闭源项目不能用 ├── 底层是 QGraphicsView 框架 → 和 QML Quick 的渲染管线不同 ├── QML 侧暴露的属性有限 → 深度定制必须写 C++ └── 模块处于维护阶段 → Qt 官方推荐迁移到 Qt Graphs(但还不够成熟)StyledCharts 选择了纯 QML 实现 + 混合渲染:
┌─────────────────────────────────────────────────────┐ │ StyledCharts 统一 API 层 │ │ (声明式 QML 接口 + 主题系统注入) │ ├─────────────────────────────────────────────────────┤ │ │ │ ┌────────────────────┐ ┌──────────────────────┐ │ │ │ QML Canvas 渲染 │ │ Qt Quick Shapes 渲染 │ │ │ │ │ │ │ │ │ │ • PieChart 饼图 │ │ • LineChart 折线图 │ │ │ │ • DonutChart 环形 │ │ • AreaChart 面积图 │ │ │ │ • BarChart 柱状图 │ │ • Sparkline 迷你图 │ │ │ │ • GaugeChart 仪表 │ │ │ │ │ │ │ │ 优势:抗锯齿更优 │ │ │ │ 优势:填充/圆弧高效 │ │ 性能更好,动画流畅 │ │ │ └────────────────────┘ └──────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────┐ │ │ │ ChartTheme.js (继承自 Style Pack ThemeManager)│ │ │ │ 6套主题 × 每套6色 chartColors 调色板 │ │ │ └──────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘按图表特性分配渲染引擎——饼图、柱状图用 Canvas(填充矩形和圆弧是 Canvas 的强项),折线图、面积图用 Shapes(路径抗锯齿和动画性能更好)。这不是偷懒,是有意为之的工程取舍。
9种图表一览
3.1 折线图 StyledLineChart
支持多系列、平滑曲线、数据点标记、渐变填充区域:
StyledLineChart { anchors.fill: parent title: "月度收入趋势" chartTheme: ChartThemeManager.themeByName("midnight-blue") model: ListModel { ListElement { month: "1月"; value: 4200 } ListElement { month: "2月"; value: 5800 } ListElement { month: "3月"; value: 6100 } ListElement { month: "4月"; value: 7300 } ListElement { month: "5月"; value: 8900 } ListElement { month: "6月"; value: 12400 } } xField: "month" yField: "value" smooth: true showArea: true }3.2 柱状图 StyledBarChart
圆角渐变柱体、分组对比、数值标签:
StyledBarChart { anchors.fill: parent chartTheme: ChartThemeManager.themeByName("dark-neon") barRadius: 6 showValues: true model: ListModel { ListElement { category: "Q1"; sales: 320; profit: 180 } ListElement { category: "Q2"; sales: 480; profit: 260 } ListElement { category: "Q3"; sales: 560; profit: 310 } ListElement { category: "Q4"; sales: 720; profit: 420 } } }3.3 饼图 & 环形图
饼图带扇区间隙和引导线标签;环形图支持中心数值显示:
StyledDonutChart { anchors.fill: parent chartTheme: ChartThemeManager.themeByName("cyber-dark") centerText: "¥12,400" centerLabel: "本月营收" innerRatio: 0.65 model: ListModel { ListElement { name: "会员充值"; value: 6800 } ListElement { name: "散客消费"; value: 3200 } ListElement { name: "外卖收入"; value: 2400 } } }3.4 仪表盘 StyledGaugeChart
色区分段、指针动画、阈值变色——适合做速度表、温度监控、CPU 占用等场景。
3.5 面积图 / 雷达图 / 散点图 / 迷你图
每种图表都有完整的属性接口和主题适配,这里不逐一展开。
0x04 主题系统:6套暗黑主题一键切换
这是 StyledCharts 和"自己手写 Canvas 图表"拉开差距的核心。
// 一行代码切换主题,所有图表联动 ChartThemeManager.currentTheme = "midnight-blue" // 6套内置主题 // ├── midnight-blue 深蓝沉稳,适合数据大屏 // ├── dark-neon 霓虹高对比,适合科技风Dashboard // ├── cyber-dark 赛博朋克风,紫+青撞色 // ├── forest-night 暗绿+暖橙,适合环保/健康类 // ├── obsidian 纯黑白灰极简,适合专业报表 // └── sunset-dark 暗红+金色,适合金融/股票类每套主题包含 6 色 chartColors 调色板,图表会自动从调色板取色。如果你要自定义主题,只需实现ChartTheme接口:
ChartTheme { name: "my-brand" backgroundColor: "#0D1117" chartColors: ["#58A6FF", "#3FB950", "#D29922", "#F85149", "#BC8CFF", "#79C0FF"] gridColor: "#21262D" textColor: "#C9D1D9" fontFamily: "Microsoft YaHei" }和 Qt Charts 的对比
| 维度 | Qt Charts | StyledCharts |
|---|---|---|
| 授权 | GPL v3(闭源需商用License) | MIT(随意使用) |
| 样式风格 | 默认工业风,暗黑适配困难 | 6套暗黑主题开箱即用 |
| 技术栈 | C++ QGraphicsView | 纯 QML,混合渲染 |
| QML 集成 | 需要 QApplication(不能用 QGuiApplication) | 原生 Qt Quick,无额外依赖 |
| 定制难度 | 深度定制需写 C++ | 纯 QML 属性声明,所见即所得 |
| 包体积 | 依赖 Qt Charts 模块 | 零额外依赖 |
| 主题联动 | 独立主题系统 | 与 Style Pack 共享 ThemeManager |
| 适用场景 | 快速原型、学术用途 | 商业桌面应用、暗黑风格 Dashboard |
实际使用场景
StyledCharts 适合这几类项目:
- 数据监控大屏:工控上位机、IoT 设备面板、服务器监控
- 企业管理软件:ERP/CRM 的报表模块、财务看板
- 多媒体应用:音频频谱、视频编码参数展示
- 工具类桌面软件:股票行情、健康管理、运动数据
一个典型的 Dashboard 集成只需要:
import QtQuick 2.15 import "StyledCharts/" import "StyledCharts/themes/" Rectangle { color: ChartThemeManager.currentTheme.backgroundColor ChartThemeManager { id: themeManager } GridLayout { anchors.fill: parent columns: 3 rowSpacing: 16; columnSpacing: 16 StyledLineChart { Layout.fillWidth: true; Layout.fillHeight: true title: "实时流量" } StyledBarChart { Layout.fillWidth: true; Layout.fillHeight: true title: "分类统计" } StyledDonutChart { Layout.fillWidth: true; Layout.fillHeight: true centerText: "87%" centerLabel: "完成率" } StyledGaugeChart { Layout.columnSpan: 2; Layout.fillWidth: true; Layout.fillHeight: true title: "CPU 占用" } StyledRadarChart { Layout.fillWidth: true; Layout.fillHeight: true title: "能力评估" } } }与 Qt Style Pack 的生态联动
如果你已经用过Qt Style Pack v2.0(33个 QML UI 组件 + 6套暗黑主题),那 StyledCharts 就是它的"图表拼图":
Qt Style Pack v2.0 → 按钮、输入框、卡片、弹窗、导航... 界面控件统一 + StyledCharts v1.0 → 折线、柱状、饼图、仪表盘... 数据展示统一 = 完整暗黑 Dashboard 方案 → 控件 + 图表共享主题,视觉语言一致不需要分别调两套主题系统——Style Pack 改了主题色,StyledCharts 自动跟随。
后续规划
- v1.1:补充雷达图和散点图的高级交互(tooltip、点击选中)
- v2.0:引入 C++ QQuickPaintedItem 高性能后端,支持 10 万+ 数据点实时渲染(传感器/行情场景)
- 主题市场:开放社区主题贡献,用户自制主题可共享
最后
QML 生态不缺功能强大的库,但缺"开箱即好看"的组件。
StyledCharts 不追求大而全——它只做一件事:让你的 QML Dashboard 不再丑。
如果你正在做 Qt/QML 桌面项目,被数据可视化的样式问题折磨过,希望这套组件能帮你省掉那些重复造轮子的时间。
作者:仁莱枫,大龄 C++/Qt 程序员,正在独立开发者路上探索。
欢迎关注,后续会持续分享 QML 开发实战经验和独立开发者成长记录。
