C++ Qt开发:Charts绘图组件概述
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QCharts
二维绘图组件的常用方法及灵活运用。
Qt Charts 提供了一个强大且易于使用的工具集,用于在 Qt 应用程序中创建各种类型的图表和图形可视化,该模块提供了多种类型的图表,包括折线图、散点图、条形图、饼图等。这使得开发人员能够轻松地将数据以直观的方式呈现给用户,增强应用程序的可视化效果。
Qt Charts 组件基于GraphicsView
架构,核心由QChartView
和QChart
两个组件构成。其中,QChartView
的父类是QGraphicsView
,它负责管理数据集的显示。而QChart
则是图表的主要类,用于定义图表的结构和样式。整体来说,QChartView
通过显示QChart
来呈现图表视图。其中QChart
的继承关系如下图所示;
如果要在项目中使用绘图模块,则必须在项目的*.pro
文件中引用Qt+=charts
并在主函数中包含绘图头文件,如下所示;
#include <QtCharts>
using namespace QtCharts;
或者直接使用宏定义的方式;
#include <QtCharts>
Qt_CHARTS_USE_NAMESPACE
此外,为了能够让界面支持中文汉字,我们通常会直接引入如下代码至mainwindow.h
头文件中;
#include <QMainWindow>
#include <QtCharts>
QT_CHARTS_USE_NAMESPACE
// 解决MSVC编译时,界面汉字乱码的问题
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
以下是 QChart
类的一些常用方法的概述,说明和表格:
方法 | 描述 |
---|---|
setTitle(const QString &title) |
设置图表的标题 |
setTitleFont(const QFont &font) |
设置图表标题的字体 |
setTitleBrush(const QBrush &brush) |
设置图表标题的画刷(颜色和填充) |
setTheme(QChart::ChartTheme theme) |
设置图表的主题,包括颜色和样式 |
addSeries(QAbstractSeries *series) |
向图表中添加数据系列 |
removeSeries(QAbstractSeries *series) |
从图表中移除指定的数据系列 |
createDefaultAxes() |
创建默认的坐标轴 |
setAxisX(QAbstractAxis *axis, QAbstractSeries *series = nullptr) |
设置图表的 X 轴。如果未指定系列,则应用于所有系列 |
setAxisY(QAbstractAxis *axis, QAbstractSeries *series = nullptr) |
设置图表的 Y 轴。如果未指定系列,则应用于所有系列 |
legend() |
返回图表的图例对象 |
setAnimationOptions(QChart::AnimationOptions options) |
设置图表的动画选项 |
createDefaultGraphicsView() |
创建默认的图形视图(QGraphicsView ),用于显示图表 |
addAxis(QAbstractAxis *axis, Qt::Alignment alignment) |
将指定的坐标轴添加到图表中,并指定对齐方式 |
removeAxis(QAbstractAxis *axis) |
从图表中移除指定的坐标轴 |
axisX(QAbstractSeries *series = nullptr) |
返回图表的 X 轴。如果未指定系列,则返回第一个 X 轴 |
axisY(QAbstractSeries *series = nullptr) |
返回图表的 Y 轴。如果未指定系列,则返回第一个 Y 轴 |
setPlotAreaBackgroundBrush(const QBrush &brush) |
设置图表绘图区域的背景画刷 |
setPlotAreaBackgroundVisible(bool visible) |
设置图表绘图区域的背景是否可见 |
setBackgroundBrush(const QBrush &brush) |
设置整个图表的背景画刷 |
setBackgroundRoundness(qreal diameter) |
设置图表背景的圆角直径 |
setMargins(const QMargins &margins) |
设置图表的外边距 |
setTheme(QChart::ChartTheme theme) |
设置图表的主题 |
注意,上述表格中的方法并非 exhaustive,只是介绍了一些常见的和常用的方法。在实际使用中,可以根据需要查阅官方文档获取更详细的信息。
1.1 绘制折线图
接着我们来创建一个最基本的折线图,首先需要使用图形界面中的Graphics View
组件做好UI布局,但由于该组件并不是用于绘制图形的,所以如果需要绘制图形则要在组件上右键,选中提升为按钮将其提升为绘图组件,如下图;
此时会弹出如下所示的提示框,我们直接输入QChartView
类名称,并点击添加按钮,最后选择提升按钮,此时组件将将被支持绘制图形;
为了能让后续的代码能够更更容易的被读着理解,此处还需要为读者提供一份QGraphicsView
组件的常用方法,如下表格是QGraphicsView
的一些常用方法的概述:
方法 | 描述 |
---|---|
QGraphicsView(QWidget *parent = nullptr) |
默认构造函数,创建一个QGraphicsView 对象。 |
setScene(QGraphicsScene *scene) |
将指定的QGraphicsScene 设置为视图的场景。 |
scene() const |
获取当前视图关联的场景。 |
setRenderHint(QPainter::RenderHint hint, bool on = true) |
设置渲染提示,例如抗锯齿等。 |
setRenderHints(QPainter::RenderHints hints) |
设置多个渲染提示。 |
renderHints() const |
获取当前的渲染提示。 |
setViewportUpdateMode(ViewportUpdateMode mode) |
设置视口更新模式,决定何时重绘视口。 |
setSceneRect(const QRectF &rect) |
设置场景矩形,指定在视图中可见的场景区域。 |
setSceneRect(qreal x, qreal y, qreal w, qreal h) |
设置场景矩形,指定在视图中可见的场景区域。 |
sceneRect() const |
获取当前场景矩形。 |
setTransform(const QTransform &matrix, bool combine = false) |
设置视图的坐标变换矩阵。 |
resetTransform() |
重置视图的坐标变换矩阵为单位矩阵。 |
translate(qreal dx, qreal dy) |
将视图进行平移。 |
rotate(qreal angle) |
将视图进行旋转。 |
scale(qreal sx, qreal sy) |
将视图进行缩放。 |
resetMatrix() |
将视图的坐标变换矩阵重置为单位矩阵。 |
setViewportMargins(int left, int top, int right, int bottom) |
设置视口的边缘,以保留用于显示视图的场景区域之外的空间。 |
setBackgroundBrush(const QBrush &brush) |
设置视图的背景刷。 |
viewport() const |
获取视口窗口部件,即视图的直接子部件。 |
setOptimizationFlag(OptimizationFlag flag, bool enabled = true) |
启用或禁用指定的优化标志,以提高性能。 |
optimizationFlag(OptimizationFlag flag) const |
获取指定的优化标志状态。 |
centerOn(const QGraphicsItem *item) |
将视图中心对准指定的图形项。 |
centerOn(const QPointF &pos) |
将视图中心对准指定的场景坐标。 |
setInteractive(bool allowed) |
启用或禁用与场景中的项的交互。 |
setDragMode(DragMode mode) |
设置拖动模式,用于选择或移动项。 |
setViewportMargins(int left, int top, int right, int bottom) |
设置视口的边缘,以保留用于显示视图的场景区域之外的空间。 |
viewport() const |
获取视口窗口部件,即视图的直接子部件。 |
这些方法提供了对QGraphicsView
的各种设置和操作,用于管理视图的外观和行为。可以根据实际需要选择适当的方法进行使用。
接着,我们来实现一个简单的绘图功能,在MainWindow
构造函数中我们首先通过new QChart()
创建一个图表类,接着通过使用ui->graphicsView->setChart
方法可以将QChart()
类附加到QGraphicsView
图形组件上,当有了组件指针以后,就可以动态的通过折线图的规则来创建图例,当有了图例以后则就可以通过series0->append()
方法依次向图形表格中追加记录。
以下是对功能的概述:
- 创建图表和序列:
- 创建一个
QChart
对象,并设置图表标题。 - 将图表添加到
QChartView
中,以便在UI中显示。 - 创建两个曲线序列
QLineSeries
,分别代表一分钟和五分钟的系统负载。 - 将这两个序列添加到图表中。
- 创建一个
- 设置图表属性:
- 设置图表的渲染提示,以提高图表的渲染质量。
- 设置图表的主题色。
- 创建坐标轴:
- 创建 X 轴和 Y 轴对象,并设置它们的范围、标题、格式和刻度。
- 为每个序列设置相应的坐标轴。
- 初始化数据:
- 使用
QRandomGenerator
生成介于0和100之间的随机整数,模拟系统负载的变化。 - 将生成的随机整数添加到两个曲线序列中,分别对应一分钟和五分钟的负载。
- 在X轴上递增,以模拟时间的推移。
- 使用
- 清空图例和赋予数据:
- 获取序列的指针。
- 清空曲线序列的数据,以便重新加载新的数据。
- 通过循环生成的随机数填充曲线序列。
总体来说,这段代码创建了一个简单的系统性能统计图,其中包括两条曲线,每条曲线代表不同时间段的系统负载。通过使用Qt Charts
模块,可以轻松创建并显示这样的图表。
#include <QRandomGenerator>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ---------------------------------------------------
// 创建图表的各个部件
// ---------------------------------------------------
QChart *chart = new QChart();
chart->setTitle("系统性能统计图");
// 将Chart添加到ChartView
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
// 设置图表主题色
ui->graphicsView->chart()->setTheme(QChart::ChartTheme(0));
// 创建曲线序列
QLineSeries *series0 = new QLineSeries();
QLineSeries *series1 = new QLineSeries();
series0->setName("一分钟负载");
series1->setName("五分钟负载");
// 序列添加到图表
chart->addSeries(series0);
chart->addSeries(series1);
// 其他附加参数
series0->setPointsVisible(false); // 设置数据点可见
series1->setPointLabelsVisible(false); // 设置数据点数值可见
// 创建坐标轴
QValueAxis *axisX = new QValueAxis; // X轴
axisX->setRange(1, 100); // 设置坐标轴范围
axisX->setTitleText("X轴标题"); // 标题
axisX->setLabelFormat("%d %"); // 设置x轴格式
axisX->setTickCount(3); // 设置刻度
axisX->setMinorTickCount(3);
QValueAxis *axisY = new QValueAxis; // Y轴
axisY->setRange(0, 100); // Y轴范围(-0 - 20)
axisY->setTitleText("Y轴标题"); // 标题
axisY->setLabelFormat("%d %"); // 设置y轴格式
axisY->setTickCount(3); // 设置刻度
axisY->setMinorTickCount(3);
// 设置X于Y轴数据集
chart->setAxisX(axisX, series0); // 为序列设置坐标轴
chart->setAxisY(axisY, series0);
chart->setAxisX(axisX, series1); // 为序列设置坐标轴
chart->setAxisY(axisY, series1);
// ---------------------------------------------------
// 开始初始化数据
// ---------------------------------------------------
// 获取指针
series0=(QLineSeries *)ui->graphicsView->chart()->series().at(0);
series1=(QLineSeries *)ui->graphicsView->chart()->series().at(1);
// 清空图例
series0->clear();
series1->clear();
// 赋予数据
qreal t=0,intv=1;
for(int i=1;i<100;i++)
{
// 生成一个介于0和100之间的随机整数
int randomInt = QRandomGenerator::global()->bounded(101);
int randomInt2 = QRandomGenerator::global()->bounded(84);
series0->append(t,randomInt2); // 设置轴粒度以及数据
series1->append(t,randomInt); // 此处用随机数替代
t+=intv; // X轴粒度
}
}
当程序被编译运行后,读着可看到如下图所示的模拟数据输出;
1.2 绘制饼状图
接着来实现饼状图的绘制,此处我们增加两个graphicsView
组件来分别绘制两个不同的饼状图,饼状图A用于统计CPU利用率,由于只有两个数据集,所以只需要构建两个QPieSlice
即可,代码如下所示;
void MainWindow::printA()
{
// 构造数据 [已用CPU%] [剩余CPU%]
QPieSlice *slice_1 = new QPieSlice(QStringLiteral("已使用"), 0.6, this);
slice_1->setLabelVisible(true);
QPieSlice *slice_2 = new QPieSlice(QStringLiteral("可用"), 0.4, this);
slice_2->setLabelVisible(true);
// 将两个饼状分区加入series
QPieSeries *series = new QPieSeries(this);
series->append(slice_1);
series->append(slice_2);
// 创建Chart画布
QChart *chart = new QChart();
chart->addSeries(series);
// 设置显示时的动画效果
chart->setAnimationOptions(QChart::AllAnimations);
chart->setTitle("系统CPU利用率");
// 将参数设置到画布
ui->graphicsView_A->setChart(chart);
ui->graphicsView_A->setRenderHint(QPainter::Antialiasing);
ui->graphicsView_A->chart()->setTheme(QChart::ChartTheme(0));
}
饼状图B的构建与A保持一致,只需要根据规则定义对图表中的元素进行增减即可,但需要注意由于饼状图100%是最大值,所以再分配时需要考虑到配额的合理性。
void MainWindow::printB()
{
// 构造数据 [C盘%] [D盘%] [E盘%]
QPieSlice *slice_c = new QPieSlice(QStringLiteral("C盘"), 0.2, this);
slice_c->setLabelVisible(true);
QPieSlice *slice_d = new QPieSlice(QStringLiteral("D盘"), 0.3, this);
slice_d->setLabelVisible(true);
QPieSlice *slice_e = new QPieSlice(QStringLiteral("E盘"),0.5,this);
slice_e->setLabelVisible(true);
// 将两个饼状分区加入series
QPieSeries *series = new QPieSeries(this);
series->append(slice_c);
series->append(slice_d);
series->append(slice_e);
// 创建Chart画布
QChart *chart = new QChart();
chart->addSeries(series);
// 设置显示时的动画效果
chart->setAnimationOptions(QChart::AllAnimations);
chart->setTitle("系统磁盘信息");
// 将参数设置到画布
ui->graphicsView_B->setChart(chart);
ui->graphicsView_B->setRenderHint(QPainter::Antialiasing);
// 设置不同的主题
ui->graphicsView_B->chart()->setTheme(QChart::ChartTheme(3));
}
运行上述程序,则可以输出两个不同的饼状图,如下图所示;
1.3 绘制柱状图
与饼状图的绘制方法一致,在绘制柱状图时只需要根据QBarSeries
类的定义对特有元素进行填充即可,当数据集被填充后既可以直接调用绘图方法将数据刷新到组件上。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 创建人名
QBarSet *set0 = new QBarSet("张三");
QBarSet *set1 = new QBarSet("李四");
QBarSet *set2 = new QBarSet("王五");
// 分别为不同人添加bu不同数据集
*set0 << 1 << 2 << 8 << 4 << 6 << 6;
*set1 << 5 << 2 << 5 << 4 << 5 << 3;
*set2 << 5 << 5 << 8 << 15 << 9 << 5;
// 将数据集关联到series中
QBarSeries *series = new QBarSeries();
series->append(set0);
series->append(set1);
series->append(set2);
// 增加顶部提示
QChart *chart = new QChart();
chart->addSeries(series);
chart->setTitle("当前人数统计柱状图");
chart->setAnimationOptions(QChart::SeriesAnimations);
// 创建X轴底部提示
QStringList categories;
categories << "周一" << "周二" << "周三" << "周四" << "周五" << "周六";
QBarCategoryAxis *axis = new QBarCategoryAxis();
axis->append(categories);
chart->createDefaultAxes();
chart->setAxisX(axis, series);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
// 将参数设置到画布
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
// 设置主题
ui->graphicsView->chart()->setTheme(QChart::ChartTheme(0));
}
运行代码后则可以输出如下图所示的三个人的柱状统计图;
至此本章内容就结束了,通过本章内容读着应该能掌握GraphicsView
绘图组件是如何提升的,并如何利用该组件实现简单的绘制工作,从下一章开始我们将依次深入分析常用的图形类,并实现一个更加实用的小功能,能够让读者学以致用充分发挥Qt图形组件的强大功能。
C++ Qt开发:Charts绘图组件概述的更多相关文章
- Android开发四大组件概述
这个文章主要是讲Android开发的四大组件,本文主要分为 一.Activity具体解释 二.Service具体解释 三.Broadcast Receiver具体解释 四.Content Provid ...
- C++框架_之Qt的开始部分_概述_安装_创建项目_快捷键等一系列注意细节
C++框架_之Qt的开始部分_概述_安装_创建项目_快捷键等一系列注意细节 1.Qt概述 1.1 什么是Qt Qt是一个跨平台的C++图形用户界面应用程序框架.它为应用程序开发者提供建立艺术级图形界面 ...
- Qt开发环境下载和安装
Qt是跨平台的图形开发库,目前由Digia全资子公司 Qt Company 独立运营,官方网址: http://www.qt.io/ 也可以访问Qt项目域名:http://qt-project.org ...
- qt qml qchart 图表组件
qt qml qchart 图表组件 * Author: Julien Wintz * Created: Thu Feb 13 23:41:59 2014 (+0100) 这玩意是从chart.js迁 ...
- win使用MSYS2安装Qt开发环境
原文链接 MSYS2 下载地址: pacman的具体用法 有pacman的具体使用方法.我们首先对系统升级 我们首先对系统升级 pacman -Syu 就会检测整个系统可以升级的组件,并自动下载安装, ...
- Qt之QCustomPlot绘图(一)配置和第一个例子
最近一个用Qt开发的项目需要绘制坐标曲线,我在老师的指点下使用了QCustomPlot这个插件,使用方法简单,功能还算不错. 可是在网上找了很多资料和博文都只是将官方提供的例子演示一遍,没有系统全面的 ...
- 基于QT开发的第三方库
基于Qt开发的第三方库 分类: Qt2014-02-12 11:34 1738人阅读 评论(0) 收藏 举报 QT第三方库 目录(?)[+] 文章来源:http://blog.csdn.net ...
- SpringMVC 框架系列之组件概述与配置详解
在上一篇文章 SpringMVC 框架系列之初识与入门实例 的实例中,我们已经知道,SpringMVC 框架是一个 web 层的框架,本篇文章就详细解释一下 SpringMVC 框架具体文件的配置以及 ...
- 使用Qt开发绘制多个设备的流量曲线图(附带项目图)
一.说明: 在实际项目中,主要是使用Qt开发CS程序,当然主要是客户端.公司项目中有这个需求是实时显示多个设备的流量曲线图,设备将流量信息发给服务端,服务端再将信息通过Socket发给Qt客户端,Qt ...
- Android开发 ---基本UI组件2:图像按钮、单选按钮监听、多选按钮监听、开关
Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个按钮 <?xml version="1.0" encoding=" ...
随机推荐
- iOS添加图片
添加一个按钮 将图片添加到
- 在线问诊 Python、FastAPI、Neo4j — 创建 检查节点
目录 症状数据 创建节点 根据不同的症状,会建议做些相对应的检验.检查 症状数据 examine_data.csv 建议值用""引起来.避免中间有,号造成误识别 检查 " ...
- 如何用ppt打印9张一面,并且去除边距?
如何用ppt打印9张一面,并且去除边距? 方法其实很简单,答主不要在ppt软件的打印选项里设置[每页打印9张幻灯片],而是使用默认的[每页打印1张幻灯片]. 然后去[打印机属性]里设置,我是 ...
- 嵌入式BI的精解与探索
摘要:本文由葡萄城技术团队原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 1996年,商业智能(BI)的概念首次浮现,随后的20多年间,商 ...
- python---简单最大类间方差法(OTSU)算法
from matplotlib import pyplot as plt # cv2.imread()用于读取图片文件 # imread函数有两个参数,第一个参数是图片路径,第二个参数表示读取图片的形 ...
- 什么???CSS也能原子化!
1.什么是原子化 CSS? Atomic CSS is the approach to CSS architecture that favors small, single-purpose class ...
- Intervals 题解
Intervals 题目大意 给定 \(m\) 条形如 \((l_i,r_i,a_i)\) 的规则,你需要求出一个长为 \(n\) 的分数最大的 01 串的分数,其中一个 01 串 \(A\) 的分数 ...
- 从零用VitePress搭建博客教程(3) - VitePress页脚、标题logo、最后更新时间等相关细节配置
接上一节:从零用VitePress搭建博客教程(2) –VitePress默认首页和头部导航.左侧导航配置 五.默认主题相关细节配置 关于默认主题的标题,logo.页脚,最后更新时间等相关细节配置,我 ...
- 虹科分享 | 一起聊聊Redis企业版数据库与【微服务误解】那些事儿!
如今,关于微服务依然存在许多误解,企业盲目追求这种炫酷技术并不可取.同时,这种盲目行为对于希望用微服务来有效解决问题的公司很不利.不是说任何特定的技术都是缺乏实际价值的,如微服务.Kubernetes ...
- POSIX 真的不适合对象存储吗?
最近,留意到 MinIO 官方博客的一篇题为"在对象存储上实现 POSIX 访问接口是坏主意"的文章,作者以 S3FS-FUSE 为例分享了通过 POSIX 方式访问 MinIO ...