Qt图表功能学习

发布于:2025-09-09 ⋅ 阅读:(16) ⋅ 点赞:(0)

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)

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)

#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)

#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)

#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 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)中添加:

QT += charts

4.2 包含必要的头文件

#include <QChart>
#include <QChartView>
#include <QValueAxis>
#include <QSplineSeries>  // 或其他系列类型

QT_CHARTS_USE_NAMESPACE  // 使用Qt Charts命名空间

4.3 创建图表的基本步骤

  1. 创建图表和坐标轴
// 创建图表
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. 创建数据系列并添加数据
// 创建曲线系列
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. 设置图表属性
// 设置图表标题
chart->setTitle("我的图表");

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

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

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

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

5. 常用功能示例

5.1 动态添加数据点

// 假设我们有一个定时器,每秒添加一个新的数据点
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 多个数据系列

// 创建第一个系列
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 自定义图表主题

// 设置预定义主题
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 图表交互

// 启用图表交互功能
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);
    }
};

网站公告

今日签到

点亮在社区的每一天
去签到