Qt图表功能学习

Qt图表功能学习

1. 项目概述

本项目展示了如何使用Qt Charts模块创建图表,实现温度与时间的曲线关系展示。Qt Charts是Qt提供的一个强大的图表绘制模块,可以方便地创建各种类型的图表,如折线图、曲线图、柱状图、饼图等。

1.1 项目结构

复制代码
47/
├── 47.pro          # 项目配置文件
├── main.cpp        # 主函数入口
├── widget.h        # Widget类头文件
├── widget.cpp      # Widget类实现文件
└── widget.ui       # 界面设计文件

1.2 功能特点

  • 创建温度与时间的曲线图表
  • 设置坐标轴范围和标题
  • 自定义曲线样式和颜色
  • 使用QSplineSeries创建平滑曲线

2. 代码实现

2.1 项目配置文件 (47.pro)

qmake 复制代码
QT       += core gui charts

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

关键点说明:

  • QT += charts - 添加Qt Charts模块支持,这是使用图表功能的必要配置

2.2 主函数 (main.cpp)

cpp 复制代码
#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

2.3 Widget类头文件 (widget.h)

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QChart>      // 图表类
#include <QChartView>  // 图表视图类

QT_CHARTS_USE_NAMESPACE // using namespace QT_CHARTS_NAMESPACE

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

关键点说明:

  • #include <QChart>#include <QChartView> - 包含图表相关的头文件
  • QT_CHARTS_USE_NAMESPACE - 使用Qt Charts命名空间,避免每次使用图表类时都要加上命名空间前缀

2.4 Widget类实现文件 (widget.cpp)

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QValueAxis>      // 数值坐标轴
#include <QSplineSeries>   // 曲线
//#include <QLineSeries>   // 折线

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 1.创建一个图表视图
    // QChartView *chartView = new QChartView();

    // 2.创建一个图表
    QChart *chart = new QChart();

    // 3.创建坐标轴
    QValueAxis *valueAxisX = new QValueAxis();
    QValueAxis *valueAxisY = new QValueAxis();

    // 4.设置坐标轴的范围
    valueAxisX->setRange(0, 5000);
    valueAxisY->setRange(0, 100);

    // 5.设置坐标轴的标题和显示的格式
    valueAxisX->setTitleText("时间/ms");
    valueAxisY->setTitleText("温度/°C");
    valueAxisX->setLabelFormat("%d");
    valueAxisY->setLabelFormat("%d");

    // 设置xy的显示的格式
    //    valueAxisX->setTickCount(10);
    //    valueAxisY->setTickCount(10);

    // 6.图表添加坐标轴
    chart->createDefaultAxes();
    chart->addAxis(valueAxisX, Qt::AlignBottom);
    chart->addAxis(valueAxisY, Qt::AlignLeft);

    // 7.设置图表的标题以及图例显示是否需要
    chart->setTitle("温度与时间曲线");
    chart->legend()->setVisible(false);

    // 8.创建曲线对象添加它的点,设置曲线的颜色
    QSplineSeries *splineSeries =  new QSplineSeries();
    splineSeries->append(0, 50);
    splineSeries->append(1000, 60);
    splineSeries->append(2000, 80);
    splineSeries->append(3000, 50);
    splineSeries->append(4000, 30);
    splineSeries->append(5000, 80);

    QPen pen(QColor(0xff5566));
    splineSeries->setPen(pen);

    // 9.图表添加曲线
    chart->addSeries(splineSeries);

    // 10.!!!!将曲线的数据与坐标轴相连!!!!注意,这个要在图表添加曲线之后
    // 附属到坐标轴上面去
    splineSeries->attachAxis(valueAxisX);
    splineSeries->attachAxis(valueAxisY);

    // 11.将图表放置于图表视图
    ui->chartView->setChart(chart);
}

Widget::~Widget()
{
    delete ui;
}

关键点说明:

  1. 图表创建流程

    • 创建图表对象 QChart
    • 创建坐标轴 QValueAxis
    • 设置坐标轴范围和标题
    • 将坐标轴添加到图表
    • 设置图表标题和图例
    • 创建曲线并添加数据点
    • 设置曲线样式
    • 将曲线添加到图表
    • 将曲线与坐标轴关联
    • 将图表设置到图表视图
  2. 坐标轴设置

    • setRange(min, max) - 设置坐标轴范围
    • setTitleText(text) - 设置坐标轴标题
    • setLabelFormat(format) - 设置坐标轴标签格式
    • setTickCount(count) - 设置刻度数量
  3. 曲线设置

    • QSplineSeries - 创建平滑曲线
    • append(x, y) - 添加数据点
    • setPen(pen) - 设置曲线样式
    • attachAxis(axis) - 将曲线与坐标轴关联

2.5 界面设计文件 (widget.ui)

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>480</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QLabel" name="label">
     <property name="text">
      <string>QChart图表示例</string>
     </property>
     <property name="alignment">
      <set>Qt::AlignCenter</set>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QChartView" name="chartView"/>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>QChartView</class>
   <extends>QGraphicsView</extends>
   <header>qchartview.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

关键点说明:

  • 界面使用垂直布局,包含一个标签和一个图表视图
  • QChartView 是一个自定义控件,继承自 QGraphicsView
  • 需要包含头文件 qchartview.h

3. Qt Charts模块详解

3.1 常用图表类型

类名 描述 用途
QLineSeries 折线图 显示离散数据点之间的直线连接
QSplineSeries 曲线图 显示平滑曲线连接的数据点
QScatterSeries 散点图 显示不连接的离散数据点
QBarSeries 柱状图 显示分类数据的柱状表示
QPieSeries 饼图 显示数据占比的圆形表示
QAreaSeries 面积图 显示数据区域填充的图表

3.2 坐标轴类型

类名 描述 用途
QValueAxis 数值坐标轴 显示数值型数据
QDateTimeAxis 日期时间坐标轴 显示日期和时间
QCategoryAxis 类别坐标轴 显示分类数据
QLogValueAxis 对数坐标轴 显示对数刻度

4. 实现步骤详解

4.1 添加Charts模块

在项目文件(.pro)中添加:

qmake 复制代码
QT += charts

4.2 包含必要的头文件

cpp 复制代码
#include <QChart>
#include <QChartView>
#include <QValueAxis>
#include <QSplineSeries>  // 或其他系列类型

QT_CHARTS_USE_NAMESPACE  // 使用Qt Charts命名空间

4.3 创建图表的基本步骤

  1. 创建图表和坐标轴
cpp 复制代码
// 创建图表
QChart *chart = new QChart();

// 创建坐标轴
QValueAxis *axisX = new QValueAxis();
QValueAxis *axisY = new QValueAxis();

// 设置坐标轴范围
axisX->setRange(0, 10);
axisY->setRange(0, 100);

// 设置坐标轴标题
axisX->setTitleText("X轴");
axisY->setTitleText("Y轴");

// 添加坐标轴到图表
chart->addAxis(axisX, Qt::AlignBottom);
chart->addAxis(axisY, Qt::AlignLeft);
  1. 创建数据系列并添加数据
cpp 复制代码
// 创建曲线系列
QSplineSeries *series = new QSplineSeries();

// 添加数据点
series->append(0, 10);
series->append(1, 20);
series->append(2, 30);
// ...

// 设置系列名称(用于图例)
series->setName("数据系列1");

// 自定义系列外观
QPen pen(QColor(0x00, 0x80, 0x80));
pen.setWidth(2);
series->setPen(pen);

// 添加系列到图表
chart->addSeries(series);

// 将系列附加到坐标轴
series->attachAxis(axisX);
series->attachAxis(axisY);
  1. 设置图表属性
cpp 复制代码
// 设置图表标题
chart->setTitle("我的图表");

// 设置图例可见性
chart->legend()->setVisible(true);
// 设置图例位置
chart->legend()->setAlignment(Qt::AlignBottom);

// 设置图表主题
chart->setTheme(QChart::ChartThemeBlueCerulean);

// 设置动画
chart->setAnimationOptions(QChart::AllAnimations);
  1. 将图表添加到视图
cpp 复制代码
// 方法1:使用已有的QChartView控件(如UI设计中添加的)
ui->chartView->setChart(chart);

// 方法2:创建新的QChartView
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);  // 抗锯齿

5. 常用功能示例

5.1 动态添加数据点

cpp 复制代码
// 假设我们有一个定时器,每秒添加一个新的数据点
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, [=]() {
    // 获取最后一个点的x值
    qreal lastX = 0;
    if (!series->points().isEmpty()) {
        lastX = series->points().last().x();
    }
    
    // 生成新的数据点
    qreal newX = lastX + 1;
    qreal newY = QRandomGenerator::global()->bounded(100);  // 随机值
    
    // 添加到系列
    series->append(newX, newY);
    
    // 如果需要,调整X轴范围以显示最新数据
    if (newX > axisX->max()) {
        axisX->setRange(axisX->min() + 1, newX);
    }
});

// 启动定时器,每秒触发一次
timer->start(1000);

5.2 多个数据系列

cpp 复制代码
// 创建第一个系列
QSplineSeries *series1 = new QSplineSeries();
series1->setName("温度1");
series1->append(0, 10);
series1->append(1, 20);
// ...

// 创建第二个系列
QSplineSeries *series2 = new QSplineSeries();
series2->setName("温度2");
series2->append(0, 15);
series2->append(1, 25);
// ...

// 设置不同颜色
series1->setPen(QPen(QColor(0xff, 0x55, 0x66), 2));
series2->setPen(QPen(QColor(0x55, 0x66, 0xff), 2));

// 添加到图表
chart->addSeries(series1);
chart->addSeries(series2);

// 附加到坐标轴
series1->attachAxis(axisX);
series1->attachAxis(axisY);
series2->attachAxis(axisX);
series2->attachAxis(axisY);

5.3 自定义图表主题

cpp 复制代码
// 设置预定义主题
chart->setTheme(QChart::ChartThemeDark);  // 深色主题

// 或者自定义图表背景
QLinearGradient backgroundGradient;
backgroundGradient.setStart(QPointF(0, 0));
backgroundGradient.setFinalStop(QPointF(0, 1));
backgroundGradient.setColorAt(0.0, QRgb(0x2F2F3F));
backgroundGradient.setColorAt(1.0, QRgb(0x1F1F2F));
backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
chart->setBackgroundBrush(backgroundGradient);

// 自定义图表边框
chart->setBackgroundPen(QPen(QRgb(0x3F3F4F)));

5.4 图表交互

cpp 复制代码
// 启用图表交互功能
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);

// 启用缩放和平移
chartView->setRubberBand(QChartView::RectangleRubberBand);
chartView->setInteractive(true);

// 处理点击事件(需要自定义QChartView子类)
class CustomChartView : public QChartView {
public:
    CustomChartView(QChart *chart, QWidget *parent = nullptr)
        : QChartView(chart, parent) {}
    
 protected:
    void mousePressEvent(QMouseEvent *event) override {
        QPointF pos = chart()->mapToValue(event->pos());
        qDebug() << "Clicked at:" << pos;
        
        // 查找最近的点
        for (auto series : chart()->series()) {
            QXYSeries *xySeries = qobject_cast<QXYSeries*>(series);
            if (xySeries) {
                // 查找最近的点逻辑...
            }
        }
        
        QChartView::mousePressEvent(event);
    }
};
相关推荐
charlie1145141914 小时前
Android开发——初步了解AndroidManifest.xml
android·xml·开发语言·学习·安卓·安全架构
丁满与彭彭4 小时前
嵌入式学习笔记--Linux系统编程阶段--DAY06进程间通信-消息队列
linux·笔记·学习
Edward.W5 小时前
用 Go + HTML 实现 OpenHarmony 投屏(hdckit-go + WebSocket + Canvas 实战)
开发语言·后端·golang
咸甜适中5 小时前
rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(二十六)windows平台运行时隐藏控制台
笔记·学习·rust·egui
钱彬 (Qian Bin)5 小时前
一文掌握工业缺陷检测项目实战(Pytorch算法训练、部署、C++ DLL制作、Qt集成)
c++·pytorch·python·qt·实战·工业缺陷检测·faster rcnn
努力努力再努力wz5 小时前
【c++进阶系列】:万字详解AVL树(附源码实现)
java·运维·开发语言·c++·redis
CHANG_THE_WORLD5 小时前
C++并发编程指南 std::promise 介绍与使用
java·开发语言·c++·promise
egoist20235 小时前
[linux仓库]性能加速的隐形引擎:深度解析Linux文件IO中的缓冲区奥秘
linux·运维·开发语言·缓存·缓冲区
Dear.爬虫5 小时前
Golang的协程调度器原理
开发语言·后端·golang