C++ Qt开发:Charts绘图组件概述

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QCharts二维绘图组件的常用方法及灵活运用。

Qt Charts 提供了一个强大且易于使用的工具集,用于在 Qt 应用程序中创建各种类型的图表和图形可视化,该模块提供了多种类型的图表,包括折线图、散点图、条形图、饼图等。这使得开发人员能够轻松地将数据以直观的方式呈现给用户,增强应用程序的可视化效果。

Qt Charts 组件基于GraphicsView架构,核心由QChartViewQChart两个组件构成。其中,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()方法依次向图形表格中追加记录。

以下是对功能的概述:

  1. 创建图表和序列:
    • 创建一个 QChart 对象,并设置图表标题。
    • 将图表添加到 QChartView 中,以便在UI中显示。
    • 创建两个曲线序列 QLineSeries,分别代表一分钟和五分钟的系统负载。
    • 将这两个序列添加到图表中。
  2. 设置图表属性:
    • 设置图表的渲染提示,以提高图表的渲染质量。
    • 设置图表的主题色。
  3. 创建坐标轴:
    • 创建 X 轴和 Y 轴对象,并设置它们的范围、标题、格式和刻度。
    • 为每个序列设置相应的坐标轴。
  4. 初始化数据:
    • 使用 QRandomGenerator 生成介于0和100之间的随机整数,模拟系统负载的变化。
    • 将生成的随机整数添加到两个曲线序列中,分别对应一分钟和五分钟的负载。
    • 在X轴上递增,以模拟时间的推移。
  5. 清空图例和赋予数据:
    • 获取序列的指针。
    • 清空曲线序列的数据,以便重新加载新的数据。
    • 通过循环生成的随机数填充曲线序列。

总体来说,这段代码创建了一个简单的系统性能统计图,其中包括两条曲线,每条曲线代表不同时间段的系统负载。通过使用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图形组件的强大功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/263869.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Git 配置多个 SSH-Key

Git 配置多个 SSH-Key &#xff08;两个都是gitee&#xff09; 先看图&#xff0c;官网固然重要&#xff0c;但是不完全行&#xff08;因为官网示例是一个gitee一个github&#xff09;&#xff0c;现在想是想多个都是gitee在他上面稍微更改即可 一般不对遇到这种问题&#xf…

Windows电脑向ipad和iOS系统共享文件夹

Windows电脑向ipad和iOS系统共享文件夹 这个方案不需要下载任何软件&#xff0c;但是要求 iOS 和 Windows 在同一个局域网内。再大的文件都可以在 iOS13 自带的的“文件App”里实时显示&#xff0c;可以直接打开。这个解决方案需要你 Windows 电脑上登陆了微软账号&#xff0c…

数字技术:引领未来的创新驱动力

数字技术&#xff0c;作为当代最具创新性和影响力的技术领域之一&#xff0c;已经在全球范围内引起了广泛的关注和研究。当前&#xff0c;数字技术正以惊人的速度改变着我们的世界&#xff0c;从日常生活到商业领域&#xff0c;无一不受到其影响。数字技术的发展不仅改变了人们…

深度学习美化图片,绝对可行,美化效果挺好 DPED

一、背景 要美化生成的图片的效果&#xff0c;找到一个 效果如下&#xff1a; 二、步骤 1、python3.6环境&#xff0c;TensorFlow 2.0.0 2、下载代码&#xff1a;https://github.com/aiff22/DPEDx 3、将要增强的照片放在以下目录中&#xff0c;没有就新建&#xff1a; dpe…

基于改进YOLOv7的绝缘子缺陷检测算法

摘要 现有的检测方法面临着巨大的挑战&#xff0c;在识别绝缘子的微小缺陷时&#xff0c;针对输电线路图像与复杂的背景。为保证输电线路的安全运行&#xff0c;提出一种改进的YOLOv 7模型&#xff0c;以提高检测结果。 首先&#xff0c;基于K-means对绝缘子数据集的目标盒进…

Python并行编程详解:发挥多核优势的艺术

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在当今计算机时代&#xff0c;充分发挥多核处理器的性能是提高程序运行效率的关键。Python作为一门强大的编程语言&#xff0c;提供了多种并行编程工具和库。本文将深入介绍Python中的并行编程&#xff0c;探讨如…

Python命名规范中的[单/双][前导/后缀]下划线小结

如图所示 出处 Single and Double Underscores in Python Names

泽攸科技SEM台式扫描电子显微镜

泽攸科技是一家国产的科学仪器公司&#xff0c;专注于研发、生产和销售原位电镜解决方案、扫描电镜整机、台阶仪、探针台等仪器。目前台式扫描电镜分为三个系列&#xff1a;ZEM15、ZEM18、ZEM20。 ZEM15台式扫描电镜&#xff1a; ZEM18台式扫描电镜&#xff1a; ZEM20台式扫描…

Rust报错:the msvc targets depend on the msvc linker but `link.exe` was not found

当我在我的 windows 电脑上安装 rust&#xff0c;然后用 cargo 新建了一个项目后&#xff0c;cargo run 会报错&#xff1a; error: linker link.exe not found| note: program not foundnote: the msvc targets depend on the msvc linker but link.exe was not foundnote: p…

H5页面这样测试,让Bug无处可逃!

部门最近的H5相关项目挺多的&#xff0c;由于团队之前接触的大多是Web项目&#xff0c;很少涉及H5&#xff0c;想着给团队成员培训下&#xff0c;减少漏测率&#xff0c;于是整理了一个文档。 别说&#xff0c;效果还挺不错的&#xff0c;连着上线6个版本&#xff0c;都没有收…

自动化边坡监测设备是什么?

随着科技的不断进步&#xff0c;我们的生活和环境也在不断地发生变化。然而&#xff0c;自然灾害仍然是我们无法完全避免的风险。其中&#xff0c;边坡滑坡就是一种常见的自然灾害。为了保护人民的生命财产安全&#xff0c;科学家们研发出了自动化边坡监测设备。 WX-WY1 自动化…

Pytorch-RealSR超分模型

1.前言 RealSR 是一种基于学习的单图像超分辨率&#xff08;SISR&#xff09;模型&#xff0c;专门针对真实世界的图像。它由腾讯 AI 实验室于 2020 年提出。 RealSR 的核心创新是提出了一种新的退化模型&#xff0c;该模型能够更好地模拟真实世界的退化过程。该模型考虑了真实…

多臂老虎机算法步骤

内容导航 类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统…

毅速:3D打印随形冷却水路助力模具行业降本、提质、增效

随着模具行业的不断发展&#xff0c;模具制造的精度和效率已经成为企业核心竞争力的重要组成部分。为了满足市场需求&#xff0c;模具行业一直在寻求新的制造技术和方法。3D打印技术的出现&#xff0c;为模具行业带来了革命性的变革。其中&#xff0c;3D打印随形冷却水路的应用…

Ubuntu 常用命令之 clear 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 clear命令在Ubuntu系统下用于清除终端屏幕的内容。这个命令没有任何参数&#xff0c;它的主要作用就是清理终端屏幕上的所有信息&#xff0c;使得屏幕看起来像是新打开的一样。 使用clear命令非常简单&#xff0c;只需要在终端中…

Day68力扣打卡

打卡记录 得到山形数组的最少删除次数&#xff08;线性DP 前后缀分解&#xff09; 链接 class Solution:def minimumMountainRemovals(self, nums: List[int]) -> int:n len(nums)pre, suf [1] * n, [1] * nfor i in range(n):for j in range(i):if nums[j] < nums[…

Liteos移植_STM32_HAL库

0 开发环境 STM32CubeMX(HAL库)keil 5正点原子探索者STM32F4ZET6LiteOS-develop分支 1 STM32CubeMX创建工程 如果有自己的工程&#xff0c;直接从LiteOS源码获取开始 关于STM32CubeMX的安装&#xff0c;看我另一篇博客STM32CubeMX安装 工程配置 创建新工程 选择芯片【STM32F…

16 寻找特定高度的地点

搜索二维数组 #include <iostream> using namespace::std; using std::cout; using std::cin; int main() {int n,m,target;cin >> n >> m;int matrix[n][m];for(int i0; i<n; i){for(int j0; j<m; j){cin >> matrix[i][j];}}cin >> tar…

求职方略-倒金字塔型自我介绍

第一步,开头第一句话提纲挈领,点出你的主要“卖点” 自我介绍的第一句话很重要,要有足够的吸引力,有足够的信息量,还要有足够的说服力,能产生先声夺人的效果。 一般的自我介绍喜欢按照时间线索依次介绍自己的经历,例如:“我大学毕业后就进入一家大公司的研发中心,工…

Ubuntu环境下使用Livox mid 360

参考文章&#xff1a; Ubuntu 20.04使用Livox mid 360 测试 FAST_LIO-CSDN博客 一&#xff1a;Livox mid 360驱动安装与测试 前言&#xff1a; Livox mid360需要使用Livox-SDK2&#xff0c;而非Livox-SDK&#xff0c;以及对应的livox_ros_driver2 。并需要修改FAST_LIO中部…