C++ Qt开发:Charts折线图绘制详解

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

折线图(Line Chart)是一种常用的数据可视化图表,用于展示随着时间、类别或其他有序变量而变化的趋势。折线图通过将数据点连接起来形成折线,直观地展示了变量之间的趋势和关系。

折线图通常用于以下环境:

  1. 时间序列数据: 显示随时间变化的数据趋势,例如股票价格、气温变化等。
  2. 比较趋势: 可以比较不同组之间的趋势,例如不同产品的销售趋势。
  3. 展示模式或关联关系: 用于显示变量之间的相关性或模式,例如销售额和广告投入之间的关系。

折线图的基本结构包括:

  • 横轴(X轴): 通常表示时间或类别。
  • 纵轴(Y轴): 表示变量的值。可以是数值,也可以是百分比或其他度量。
  • 数据点: 在图表上表示具体的数据值的点。
  • 折线: 将数据点连接起来的线,形成变化趋势。

在Qt中,可以使用图表库来创建折线图。通过在程序中添加相应的数据点,并设置合适的轴和样式,你可以轻松创建出漂亮且具有信息表达能力的折线图。

在之前的文章中笔者简单创建了一个折线图,由于之前的文章只是一个概述其目的是用于让读者理解绘图组件是如何被引用到项目中的,以及如何实际使用,本章我们将具体分析折线图的绘制功能,详细介绍图表各个部分的设置和操作,包括图标的标题、图例、边距等属性的设置,QLineSeries序列的属性设置,QValueAxis坐标轴的属性设置等,通过本章的学习读者可以掌握QChart绘图的核心方法。

1.1 图表设置

1.1.1 设置标题

首先我们来实现对图表的设置,通常情况下图表中的标题可以通过setTitle来设置,而通过setTitleFont可以设置标题字体,通常设置字体需要使用QFont类,以下是 QFont 类中常用的方法的说明和概述:

方法描述
QFont()默认构造函数,创建一个默认字体。
QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false)带参数的构造函数,创建一个具有指定族、大小、粗细和斜体属性的字体。
QString family() const返回字体的族(family)。
void setFamily(const QString &family)设置字体的族。
int pointSize() const返回字体的大小(以点为单位)。
void setPointSize(int pointSize)设置字体的大小。
int weight() const返回字体的粗细。
void setWeight(int weight)设置字体的粗细。
bool italic() const返回字体是否为斜体。
void setItalic(bool italic)设置字体是否为斜体。
QString styleName() const返回字体的样式名称。
void setStyleName(const QString &styleName)设置字体的样式名称。
bool bold() const返回字体是否为粗体。
void setBold(bool enable)设置字体是否为粗体。
bool exactMatch() const检查字体是否与指定的字体精确匹配。
QFontMetrics metrics() const返回字体的度量信息,如字符高度、宽度等。
bool operator==(const QFont &other) const比较两个字体是否相等。
bool operator!=(const QFont &other) const比较两个字体是否不相等。
QFont &operator=(const QFont &font)重载赋值运算符,用于将一个字体的值赋给另一个字体。

这些方法允许你设置和获取字体的各种属性,如族、大小、粗细、斜体等。你可以使用这些方法来创建和调整字体,以满足应用程序的设计需求。

通过创建一个 QFont 对象 titleFont,然后设置字体的家族、大小和粗细。最后,通过 setTitleFont 方法将这个字体应用到图表的标题上,具体实现代码如下所示;

// 设置顶部标题
chart->setTitle("系统性能统计图");

// 设置字体
QFont titleFont;
titleFont.setFamily("Arial");
titleFont.setPointSize(25);
titleFont.setBold(true);

// 设置图表标题的字体
chart->setTitleFont(titleFont);

你可以根据需要调整字体的其他属性,例如设置斜体、下划线等。调整 setFamilysetPointSizesetBold 等方法的参数,则用于控制这三个属性,当然如果不希望出现顶部提示则可以忽略设置setTitle属性;

1.1.2 图表主题

图表主题的选择可以通过setTheme属性设置,在Qt中默认支持的主题有8种可以选择,通过使用不同的属性可以设置不同的样式表或主题,以影响应用程序的外观和感觉。

  • Light(亮): 一种明亮的主题或样式,通常背景颜色较浅,前景颜色较深,使得界面看起来清晰明了。
  • BlueCerulean(蓝天蓝): 一个以蓝色为主调的主题,可能会给应用程序带来清新和现代的感觉。
  • Dark(暗): 一种较暗的主题,背景颜色可能较深,前景颜色相应较亮。适合创建更为暗调的用户界面。
  • BrownSand(棕沙): 以棕色为主的主题,可能给应用程序带来温暖和自然的感觉。
  • BlueNcs(蓝NCS): 一种以蓝色为主的主题,NCS 可能指的是一种颜色标准。
  • HighContrast(高对比度): 一个高对比度的主题,通常用于提供更好的可访问性,特别适用于视力受损的用户。
  • BlueIcy(蓝冷): 一种以蓝色为主,可能带有冷色调的主题。
  • Qt(默认): 使用 Qt 默认主题,这个主题通常会遵循操作系统的外观,保持一致性。

而同样的设置图表展示动画则可以通过setAnimationOptions属性来设置,通常动画属性有4种选项,这些设置通常用于控制图表和轴的动画效果。以下是简要说明:

  1. NoAnimation(无动画):
    • 不使用动画效果。图表和轴的状态变化将会立即生效,没有平滑的过渡效果。
  2. GridAxisAnimations(轴网格动画):
    • 使用动画效果来显示或隐藏轴的网格线。在显示或隐藏轴网格时,会有一个平滑的过渡效果。
  3. SeriesAnimations(数据系列动画):
    • 使用动画效果来显示或隐藏数据系列。当数据系列被添加或移除时,或者改变可见性时,会有平滑的过渡效果。
  4. AllAnimations(所有动画):
    • 同时启用轴网格动画和数据系列动画。这样会在显示或隐藏轴网格和数据系列时都有平滑的过渡效果。

这些效果的设置通常需要使用下标的方式,而下标索引是从0开始的,案例中我们使用Qt默认主题,并将动画AllAnimations完全启用,当然读者也可以将其定义为特定字符串方便使用,如下所示;

// ------------------------------------------
// 主题色定义
// ------------------------------------------
#define Theme_Light 0
#define Theme_BlueCerulean 1
#define Theme_Dark 2
#define Theme_BrownSand 3
#define Theme_BlueNcs 4
#define Theme_HighContrast 5
#define Theme_BlueIcy 6
#define Theme_Qt 7

// 设置图表主题
ui->graphicsView->chart()->setTheme(QChart::ChartTheme(Theme_Qt));

// ------------------------------------------
// 动画定义
// ------------------------------------------
#define NoAnimation 0
#define GridAxisAnimations 1
#define SeriesAnimations 2
#define AllAnimations 3

// 设置动画效果
ui->graphicsView->chart()->setAnimationOptions(QChart::AnimationOptions(AllAnimations));

当设置动画与主题色以后,再次打开程序此时就会展现出所有的过度动画以及默认的主题,如下图所示;

1.1.3 图例设置

图例设置,图例指的是上图中的顶部(一分钟负载、五分钟负载)的提示信息,通常是一个QLegend类的对象,通过QChart::legend()可以获取到图表的图例,图例是Qt组件根据数据集自动生成的,当然某些属性我们也是可以调整的,例如图例位置、颜色、字体等。

例如,设置图例在图标的上下左右四个方位,以下枚举常量代表了对齐方式,可以用于设置控件或绘图元素在其父元素中的位置。

  1. Qt::AlignTop(顶部对齐):
    • 控件或元素将与其父元素的顶部对齐。
  2. Qt::AlignBottom(底部对齐):
    • 控件或元素将与其父元素的底部对齐。
  3. Qt::AlignLeft(左对齐):
    • 控件或元素将与其父元素的左侧对齐。
  4. Qt::AlignRight(右对齐):
    • 控件或元素将与其父元素的右侧对齐。

这些对齐方式常用于设置布局、排列控件或绘图元素的位置。例如,当你使用布局管理器(如 QVBoxLayoutQHBoxLayout)时,可以通过设置对齐方式来控制子控件在父控件中的相对位置,同理当使用setAlignment()函数时就可以用于设置QChart图表中的图例位置。

// ------------------------------------------
// 设置图例属性
// ------------------------------------------

// 图例是否可见
ui->graphicsView->chart()->legend()->setVisible(true);

// 图例背景框是否可见
ui->graphicsView->chart()->legend()->setBackgroundVisible(false);

// 将图例设置到顶部
ui->graphicsView->chart()->legend()->setAlignment(Qt::AlignTop);

// 将图例设置到底部
ui->graphicsView->chart()->legend()->setAlignment(Qt::AlignBottom);

// 将图例设置到左侧
ui->graphicsView->chart()->legend()->setAlignment(Qt::AlignLeft);

// 将图例设置到右侧
ui->graphicsView->chart()->legend()->setAlignment(Qt::AlignRight);

如上代码所示,由于我们最终覆盖了上下左属性,图例将会停留在最右侧,输出效果图如下;

图例的字体与颜色也可以被自定义,字体的定义与顶部标题的定义相同,通过调用QFont来设置字体,通过QColor则用于设置颜色,字体类我们说过了,这里就说一下QColor中有哪些方法可以使用吧。

以下是 QColor 类中常用的方法的说明和概述:

方法描述
QColor()默认构造函数,创建一个无效的颜色对象。
QColor(int r, int g, int b, int a = 255)构造函数,使用RGB值和可选的透明度(Alpha通道)创建颜色对象。
QColor(Qt::GlobalColor color)构造函数,使用Qt全局颜色枚举值创建颜色对象。
QColor(const QString &name)构造函数,使用颜色名创建颜色对象。例如,“red"或”#RRGGBB"。
int red() const返回颜色的红色分量。
int green() const返回颜色的绿色分量。
int blue() const返回颜色的蓝色分量。
int alpha() const返回颜色的透明度分量(Alpha通道)。
QRgb rgb() const返回颜色的32位整数表示(0xRRGGBB)。
QColor darker(int factor = 200) const返回一个较暗的颜色,可以通过指定因子调整暗度。
QColor lighter(int factor = 150) const返回一个较亮的颜色,可以通过指定因子调整亮度。
bool isValid() const检查颜色是否为有效的颜色。
bool setNamedColor(const QString &name)设置颜色为指定颜色名。如果颜色名有效,返回 true。
bool setRgb(int r, int g, int b, int a = 255)设置颜色的RGB值和可选的透明度。如果值有效,返回 true。
bool setRgba(qreal r, qreal g, qreal b, qreal a = 1.0)设置颜色的RGB浮点值和可选的透明度。如果值有效,返回 true。
QString name() const返回颜色的名称。如果颜色是基本颜色,则返回基本颜色的名称。
QColor toRgb() const返回颜色的RGB表示。
QColor toHsv() const返回颜色的HSV表示。
QColor fromRgb(int r, int g, int b, int a = 255)静态方法,创建一个颜色对象,使用RGB值和可选的透明度。
QColor fromHsv(int h, int s, int v, int a = 255)静态方法,创建一个颜色对象,使用HSV值和可选的透明度。

这些方法允许你创建、操作和查询颜色对象的各种属性,包括RGB值、透明度、HSV值等。你可以使用这些方法来定制和操作颜色,以满足应用程序的设计需求。

由于我们并不是所有的参数都需要修改,所以可以先通过legend()->font()先将默认的属性读入,然后再其基础之上对特定的字体和颜色进行属性调整,如下我们分别调整字体颜色;

// ------------------------------------------
// 设置图例字体与颜色
// ------------------------------------------

// 获取当前字体
QFont font = ui->graphicsView->chart()->legend()->font();

// 设置字体
font.setFamily("Arial");
font.setPointSize(25);
font.setBold(true);

// 设置到页面
ui->graphicsView->chart()->legend()->setFont(font);

// 获取当前颜色
QColor color = ui->graphicsView->chart()->legend()->labelColor();

// 设置标签颜色
color.setRgb(170,0,255,255);

// 设置到页面
ui->graphicsView->chart()->legend()->setLabelColor(color);

运行后,我们可以看到图例中的数字变大了,并且居右侧对齐了,颜色则是紫色,如下图所示;

1.1.4 边距设置

边距的设置在多数时候是用不到的,因为Qt中默认的边距已经就很合理了,但是在某些时候边距也需要被调整,调整边距可以通过调用setMargins函数来实现,该函数需要接收QMargins类,该类常用于表示矩形边界。

以下是 QMargins 类中常用的方法的说明和概述:

方法描述
QMargins()默认构造函数,创建一个无边距的对象。
QMargins(int left, int top, int right, int bottom)构造函数,使用指定的边距值创建对象。
int left() const返回左边距值。
void setLeft(int left)设置左边距值。
int top() const返回上边距值。
void setTop(int top)设置上边距值。
int right() const返回右边距值。
void setRight(int right)设置右边距值。
int bottom() const返回下边距值。
void setBottom(int bottom)设置下边距值。
bool isNull() const检查边距是否为零,即是否所有边距值都为零。
bool operator==(const QMargins &other) const比较两个边距对象是否相等。
bool operator!=(const QMargins &other) const比较两个边距对象是否不相等。
QMargins &operator+=(const QMargins &margins)将另一个边距对象的值添加到当前对象。
QMargins &operator-=(const QMargins &margins)从当前对象的值中减去另一个边距对象的值。
QMargins operator+(const QMargins &margins) const返回当前对象与另一个边距对象相加的结果。
QMargins operator-(const QMargins &margins) const返回当前对象与另一个边距对象相减的结果。

QMargins 类表示矩形的边距,其包含了四个整数值,分别表示左、上、右、下的边距。这些方法允许你设置和获取边距的各个部分,进行边距的比较和运算等。这在界面布局和绘图等场景中经常用到,用于定义边距和间距。

边界的设置很简单,来看如下代码案例的演示,Qt中默认的边界值应该均为10这个可以自己去验证。

// ------------------------------------------
// 设置上下左右边界
// ------------------------------------------

QMargins mgs;

// 设置边界
mgs.setLeft(-10);
mgs.setRight(-10);
mgs.setTop(-10);
mgs.setBottom(-10);

// 刷新到图表
ui->graphicsView->chart()->setMargins(mgs);

当运行后,读者可观察图表中的变化,来体会边界值是什么,当然了如果读者设置的负数太大绘图很有可能脱离绘图区;

2.1 序列与坐标轴

2.1.1 QLineSeries序列类

首先在绘图之前,我们必须要先看一下QLineSeries折线图类,以及QValueAxis坐标轴类,此处如果读者需要绘制其他的图形,比如折线图中有另一种光滑折线图,则就需要使用QSplineSeries类,根据不同的图表需要使用不同的绘制类,此处我们就以普通折线图为例,让我们来看一下绘图类中所支持的接口吧。

QLineSeries 是 Qt 中用于绘制折线图的类,下面是关于 QLineSeries 常用的方法的说明和概述:

方法描述
void append(const QPointF &point)向折线系列中追加一个数据点。
void append(QPointF &&point)向折线系列中追加一个数据点(移动语义版本)。
void append(double x, double y)向折线系列中追加指定坐标的数据点。
void replace(int index, const QPointF &point)替换指定索引处的数据点。
void replace(int index, double x, double y)替换指定索引处的数据点,使用指定坐标。
void remove(int index)从折线系列中移除指定索引处的数据点。
void removePoints(int index, int count)从折线系列中移除指定索引开始的指定数量的数据点。
void clear()清空折线系列中的所有数据点。
QPointF at(int index) const返回指定索引处的数据点。
int count() const返回折线系列中数据点的数量。
bool isEmpty() const检查折线系列是否为空(不包含数据点)。
void setPen(const QPen &pen)设置绘制折线时使用的笔。
QPen pen() const返回当前用于绘制折线的笔。
void setPointLabelsFormat(const QString &format)设置数据点标签的显示格式。
QString pointLabelsFormat() const返回当前数据点标签的显示格式。
void setPointLabelsVisible(bool visible)设置是否显示数据点标签。
bool pointsVisible() const返回是否显示数据点标签。
void setUseOpenGL(bool enable)设置是否使用OpenGL进行渲染。
bool useOpenGL() const返回是否使用OpenGL进行渲染。
void setColor(const QColor &color)设置折线的颜色。
QColor color() const返回当前折线的颜色。
void setOpacity(qreal opacity)设置折线的透明度。
qreal opacity() const返回当前折线的透明度。

上述方法提供了一些基本的操作,例如追加、替换、移除数据点,以及设置折线的样式、颜色等属性。你可以根据需要使用这些方法来自定义和控制折线图的外观和行为。

首先我们先来实现对绘制线条的自定义,在创建序列线条时,我们通常会自定义线条的颜色,颜色的自定义可以使用QPen类来指定,以下是 QPen 类中常用的方法的说明和概述:

方法描述
QPen()默认构造函数,创建一个默认的画笔。
QPen(Qt::PenStyle style)使用指定的画笔风格创建画笔。
QPen(const QColor &color)使用指定的颜色创建画笔。
QPen(const QBrush &brush, qreal width = 0, Qt::PenStyle style = Qt::SolidLine, Qt::PenCapStyle cap = Qt::SquareCap, Qt::PenJoinStyle join = Qt::BevelJoin)使用指定的画刷、宽度、风格、端点样式和连接样式创建画笔。
void setColor(const QColor &color)设置画笔的颜色。
QColor color() const返回画笔的颜色。
void setStyle(Qt::PenStyle style)设置画笔的风格。
Qt::PenStyle style() const返回画笔的风格。
void setWidth(qreal width)设置画笔的宽度。
qreal width() const返回画笔的宽度。
void setCapStyle(Qt::PenCapStyle style)设置画笔的端点样式。
Qt::PenCapStyle capStyle() const返回画笔的端点样式。
void setJoinStyle(Qt::PenJoinStyle style)设置画笔的连接样式。
Qt::PenJoinStyle joinStyle() const返回画笔的连接样式。
void setBrush(const QBrush &brush)设置画笔的画刷。
QBrush brush() const返回画笔的画刷。
void setDashPattern(const QVector<qreal> &pattern)设置虚线的模式。
QVector<qreal> dashPattern() const返回虚线的模式。
void setDashOffset(qreal offset)设置虚线的偏移。
qreal dashOffset() const返回虚线的偏移。
void setCosmetic(bool cosmetic)设置画笔是否为“化妆品”笔。当为 true 时,笔将忽略设备的变换,保持笔宽度为一个像素。
bool isCosmetic() const返回画笔是否为“化妆品”笔。
void setTransform(const QTransform &matrix, bool combine = false)设置画笔的变换矩阵。
QTransform transform() const返回画笔的变换矩阵。
void setMiterLimit(qreal limit)设置斜接连接的限制。
qreal miterLimit() const返回斜接连接的限制。
bool operator==(const QPen &other) const比较两个画笔是否相等。
bool operator!=(const QPen &other) const比较两个画笔是否不相等。

这些方法允许你设置和获取画笔的各种属性,如颜色、风格、宽度、样式等。QPen 类用于定义在绘图中如何绘制线条和边框。你可以使用这些方法来自定义画笔,以满足应用程序的设计需求。

当有了QPen类就可以对颜色进行自定义了,读者需要注意,曲线画笔中有一个setStyle属性,该属性是用于指定画笔风格的枚举值,常用于设置 QPen 的风格。以下是这些枚举值的说明:

  1. Qt::SolidLine(实线):
    • 表示使用实线绘制。
  2. Qt::DashLine(短划线):
    • 表示使用短划线绘制,即通过交替的短线和空白段绘制。
  3. Qt::DotLine(点线):
    • 表示使用点线绘制,即通过交替的点和空白段绘制。
  4. Qt::DashDotLine(点划线):
    • 表示使用点划线绘制,即通过交替的点、短划线和空白段绘制。

这些枚举值通常用于设置画笔的风格,当有了这些前置条件以后,相信读者能更容易地理解曲线序列是如何被创建出来的了,如下代码则是一个完整版的创建流程,读者可自行参考学习;

// ------------------------------------------
// 创建曲线序列
// ------------------------------------------

QLineSeries *series0 = new QLineSeries();
QLineSeries *series1 = new QLineSeries();

// 为序列设置名字
series0->setName("一分钟负载");
series1->setName("五分钟负载");

// 为曲线指定类型和属性
QPen pen;

// 设置线条类型:Qt::SolidLine, Qt::DashLine, Qt::DotLine, Qt::DashDotLine
pen.setStyle(Qt::DotLine);
pen.setWidth(2);             // 设置序列宽度
pen.setColor(Qt::green);     // 设置绿色
series0->setPen(pen);        // 折线序列的线条设置

// 设置线条类型:Qt::SolidLine, Qt::DashLine, Qt::DotLine, Qt::DashDotLine
pen.setStyle(Qt::SolidLine);
pen.setColor(Qt::blue);      // 设置蓝色
pen.setWidth(2);             // 设置序列宽度
series1->setPen(pen);        // 折线序列的线条设置

// 为序列曲线设置颜色
QColor color;
color.setRgb(170,0,255,255);   // 紫色配色
series0->setColor(color);      // 设置序列0

// 将序列添加到图表
chart->addSeries(series0);
chart->addSeries(series1);

// -----------------------------------------------
// 其他附加参数
// -----------------------------------------------

// 序列是否可见
series0->setVisible(true);
series1->setVisible(true);

// 序列的数据点是否可见
series0->setPointsVisible(true);
series1->setPointsVisible(false);

// 序列的数据点标签是否可见
series0->setPointLabelsVisible(false);
series1->setPointLabelsVisible(true);

// 序列数据点标签显示格式
series0->setPointLabelsFormat("(@xPoint,@yPoint)");
series1->setPointLabelsFormat("@yPoint");

// 序列透明度设置
series0->setOpacity(100/10.0);
series1->setOpacity(100/10.0);

// 设置序列数据点标签颜色
QColor scolor=series0->pointLabelsColor();

scolor.setRgb(170,0,255,255);
series0->setPointLabelsColor(scolor);
series1->setPointLabelsColor(scolor);

// 设置序列数据点标签字体
QFont font = series0->pointLabelsFont();
series0->setPointLabelsFont(font);

运行上述绘制代码,读者可以看到如下图所示的案例,这里之所以很乱是为了更好的演示函数功能,读者可以自行关闭这些选项后依次观察效果;

2.1.2 QValueAxis坐标轴类

接着我们就需要设置图表中的坐标轴参数,本例中我们使用QValueAxis类的坐标轴,这是数值型坐标轴,其刚好可以与QLineSeries配合使用,当如Qt中提供了许多坐标轴,但他们都是从QAbstractAxis类继承而来的。

QValueAxis 是用于处理数值轴的类,通常用于折线图、散点图等图表类型。以下是关于 QValueAxis 常用的方法的说明和概述:

方法描述
void setRange(qreal min, qreal max)设置轴的数值范围。
void setTickCount(int count)设置轴上的刻度数量。
void setMinorTickCount(int count)设置轴上每个刻度之间的小刻度数量。
void setLabelFormat(const QString &format)设置刻度标签的显示格式。
void setLabelsVisible(bool visible)设置是否显示刻度标签。
void setTitleText(const QString &title)设置轴的标题。
void setTitleVisible(bool visible)设置是否显示轴的标题。
void setGridLineVisible(bool visible)设置是否显示网格线。
void setGridLineColor(const QColor &color)设置网格线的颜色。
void setGridLinePen(const QPen &pen)设置用于绘制网格线的笔。
void setLinePen(const QPen &pen)设置轴线的笔。
qreal min() const返回轴的最小值。
qreal max() const返回轴的最大值。
int tickCount() const返回轴上的刻度数量。
int minorTickCount() const返回轴上每个刻度之间的小刻度数量。
QString labelFormat() const返回刻度标签的显示格式。
bool isLabelsVisible() const返回是否显示刻度标签。
QString titleText() const返回轴的标题。
bool isTitleVisible() const返回是否显示轴的标题。
bool isGridLineVisible() const返回是否显示网格线。
QColor gridLineColor() const返回网格线的颜色。
QPen gridLinePen() const返回用于绘制网格线的笔。
QPen linePen() const返回轴线的笔。

这些方法提供了对数值轴的各种设置和属性获取,包括范围、刻度、标签、标题、网格线等。你可以使用这些方法来定制数值轴以满足你图表的需求。

如下是坐标轴的常用配置参数,读者可自行选择不同的函数设置使用,其完整代码如下所示;

// -----------------------------------------------
// 坐标轴配置
// -----------------------------------------------

// 创建坐标轴X
QValueAxis *axisX = new QValueAxis;

axisX->setRange(0, 10);             // 设置坐标轴范围
axisX->setLabelFormat("%.1f");      // 标签格式
axisX->setTickCount(11);            // 主分隔个数
axisX->setMinorTickCount(4);        // 设置轴上每个刻度之间的小刻度数量
axisX->setTitleText("X轴坐标");      // 标题

// 创建坐标轴Y
QValueAxis *axisY = new QValueAxis;
axisY->setRange(-2, 2);
axisY->setTitleText("Y轴坐标");
axisY->setTickCount(5);
axisY->setLabelFormat("%.2f");
axisY->setMinorTickCount(4);

// 设置坐标轴
chart->addAxis(axisX,Qt::AlignBottom);
chart->addAxis(axisY,Qt::AlignLeft);

 //序列 series0 附加坐标轴
series0->attachAxis(axisX);
series0->attachAxis(axisY);

//序列 series1 附加坐标轴
series1->attachAxis(axisX);
series1->attachAxis(axisY);

// -----------------------------------------------
// 其他附加参数
// -----------------------------------------------

// 刻度是否可见
axisX->setLineVisible(true);
axisY->setLineVisible(true);

// 坐标轴标题是否可见
axisX->setTitleVisible(true);
axisY->setTitleVisible(true);

// 轴的刻度标签是否可见
axisX->setLabelsVisible(true);
axisY->setLabelsVisible(true);

// 轴的网格线是否可见
axisX->setGridLineVisible(true);
axisY->setGridLineVisible(true);

// 次级刻度是否可见
axisX->setMinorGridLineVisible(true);
axisY->setMinorGridLineVisible(true);

// 设置坐标轴的标题的字体
QFont fontX=axisX->titleFont();
axisX->setTitleFont(font);

// 设置坐标轴刻度标签的文字颜色
QColor colorX=axisX->labelsColor();
axisX->setLabelsColor(colorX);

// 设置坐标轴刻度标签的文字字体
axisX->setLabelsFont(font);

// 网格线的颜色设置
QColor colorLine=axisX->gridLineColor();
axisX->setGridLineColor(colorLine);

// 网格线的Pen设置
QPen penW;
penW=axisX->gridLinePen();
axisX->setGridLinePen(penW);

// 设置线条颜色
axisX->setLinePen(penW);
axisX->setLinePenColor(color);

// 次级刻度网格线颜色
QColor colorC=axisX->minorGridLineColor();
axisX->setMinorGridLineColor(colorC);

// 次级刻度线Pen设置
QPen penC;
penC=axisX->minorGridLinePen();
axisX->setMinorGridLinePen(pen);

最后是对数据进行初始化,因为初始化数据之前需要拿到series对象的指针,当得到该指针后,就可以通过调用append()方法或者是<<符号进行数据的追加操作,每次递增intv循环直到cnt计数结束;

// ---------------------------------------------------
// 开始初始化数据
// ---------------------------------------------------

// 获取指针
series0=(QLineSeries *)ui->graphicsView->chart()->series().at(0);
series1=(QLineSeries *)ui->graphicsView->chart()->series().at(1);

// 清空图例
series0->clear();
series1->clear();

// 随机数初始化
qsrand(QTime::currentTime().second());

qreal t=0,y1,y2,intv=0.1;
qreal rd;
int cnt=100;
for(int i=0;i<cnt;i++)
{
    rd=(qrand() % 10)-5;       // 随机数,-5~+5
    y1=qSin(t)+rd/50;
    *series0<<QPointF(t,y1);   // 序列添加数据点
    // series0->append(t,y1);  // 序列添加数据点

    rd=(qrand() % 10)-5; //随机数,-5~+5
    y2=qCos(t)+rd/50;
    // series1->append(t,y2);  // 序列添加数据点
    *series1<<QPointF(t,y2);   // 序列添加数据点

    t+=intv;
}

运行后读者可以看到如下图所示的输出效果;

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

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

相关文章

.raw 是一个 Anndata 包中的对象,用于存储原始的单细胞数据。scanpy种如何查看 .raw 对象的内容,

1查看 .raw 对象的内容&#xff0c;可以使用以下方法&#xff1a; .raw 是一个 Anndata 包中的对象&#xff0c;用于存储原始的单细胞数据。 使用 .X 属性查看原始数据矩阵&#xff1a;.raw.X 这将返回一个 Numpy 数组&#xff0c;其中包含原始数据的数值。 使用 .var_names 属…

LZW算法

LZW算法是一种流行且高效的无损数据压缩算法。它的名称来自于它的发明者Lempel、Ziv和Welch。LZW算法通过利用重复出现的字串来实现数据的可靠压缩&#xff0c;同时保证压缩后的数据能够精确还原为原始数据。 LZW算法的基本原理很简单&#xff0c;在压缩过程中&#xff0c;它维…

Python算法例24 落单的数Ⅱ

1. 问题描述 给出3n1个非负整数元素的数组&#xff0c;除其中一个数字之外&#xff0c;其他每个数字均出现三次&#xff0c;找到这个数字。 2. 问题示例 给出[1&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;3&#xff0c;3&#xff0c;2&#xff0c;2&#xff0c;4&…

2023年都找不到工作,软件测试已经崩了?

最近后台很多粉丝给我留言&#xff1a; 2023年软件测试已经崩盘了吗&#xff0c;为什么都找不到工作了&#xff1f; 确实&#xff0c;今年经济大环境不好&#xff0c;企业也都在降本增效&#xff0c;如果技术能力还在被应届生竞争岗位的阶段&#xff0c;只会越来越难。 找不…

网站怎么才能做好SEO?网站SEO指引!!

在当今互联网的激烈竞争中&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;已成为提升网站流量和吸引更多用户的关键手段。为了帮助您更好地掌握SEO网站优化技巧&#xff0c;本文将深入探讨以下几个方面&#xff1a; 一、关键词策略 关键词策略是SEO优化的基石。正确选择…

fba海派和传统海运的区别,亚马逊 FBA货物包装技巧—站斧浏览器

fba海派和传统海运的区别 1、美国FBA海派是什么&#xff1f; 美国FBA海派即将商品通过海洋运输的方式运送到美国亚马逊FBA仓库的服务。这种方式主要适用于大批量或大件商品&#xff0c;因为相比其他物流方式&#xff0c;海派具备成本低和运载量大的优势。 2、传统海运是什么…

Vue项目如何打包

1. 确保你已经在项目根目录下安装了Vue CLI。如果没有安装&#xff0c;可以通过以下命令进行安装&#xff1a; npm install -g vue/cli 2. 在项目根目录下打开终端或命令行工具&#xff0c;运行以下命令来创建一个生产环境的打包文件&#xff1a; npm run build 这个命令会执…

汽车服务品牌网站建设的作用是什么

汽车服务涵盖多个层面&#xff0c;在保修维护这一块更是精准到了车内车外&#xff0c;无论是品牌商还是市场中各维修部&#xff0c;都能给到车辆很好的维修养护服务。如今车辆的人均拥有量已经非常高&#xff0c;也因此市场中围绕汽车相关的从业者也比较多。 首先就是拓客引流…

C语言中二维数组的存储和二进制数在底层的排列顺序

1 二维数组变量的存储 二维数组在内存中是按照先行后列的顺序存储的&#xff0c;即先存储第一行的所有元素&#xff0c;再存储第二行的所有元素&#xff0c;以此类推。每个元素在内存中占据一定的字节数&#xff0c;这个字节数由该元素的类型决定。例如&#xff0c;int类型的元…

C语言学习NO.9-指针(一)内存和地址,指针变量,指针变类型的意义,const修饰指针,指针运算,野指针,assret断言,指针的使用和传址调用

指针是什么&#xff1f; 指针理解的2个要点&#xff1a; 1.指针是内存中一个最小单元的编号&#xff0c;也就是地址&#xff1b; 2.平时口语中说的指针&#xff0c;通常指的是指针变量&#xff0c;是用来存放内存地址的变量。 总结&#xff1a;指针就是地址&#xff08;变量的地…

LIMS实验室管理软件多少钱 智慧实验室管理系统价格

随着实验室管理需求的日益复杂&#xff0c;实验室信息管理系统(LIMS)逐渐成为实验室管理的必备工具。然而&#xff0c;对于许多实验室而言&#xff0c;选择合适的LIMS系统是一项挑战&#xff0c;其中价格是一个重要的考虑因素。本文将以白码LIMS系统为例&#xff0c;探讨LIMS实…

不忍学弟学妹受苦受难!!!逐一讲解发动机原理实验报告(2)

固体火箭发动机动态燃速测试实验 二、实验数据 1、药柱的具体结构&#xff08;绘制&#xff09;这个参考实验报告册即可&#xff0c;原图。 有时候我也纳闷&#xff0c;原图你还让学生抄什么抄呢&#xff1f; 2、实验采集到的P-t和F-t曲线图&#xff08;我做的仅供参考&…

内部FLASH模拟EPPROM

本例程基于STM32F103ZET6 FLASH大小为512K。 介绍FLASH 不同型号的 STM32&#xff0c;其 FLASH 容量也有所不同&#xff0c;最小的只有 16K 字节&#xff0c;最大的则达到了 1024K 字节。我们的精英 STM32 开发板选择的是 STM32F103ZET6 的 FLASH 容量为 512K 字节&#xff0…

又老性能又差,为什么好多公司依然选择 RabbitMQ?

大家好&#xff0c;我是君哥。 RabbitMQ 这个消息队列相信很多程序员都用过&#xff0c;我第一次使用是在 2016 年&#xff0c;确实是一个老牌的消息队列了&#xff0c;但是为什么一直没有被淘汰呢&#xff1f;今天来聊一聊这个话题。 老旧差 发布历史 为什么说 RabbitMQ 老…

HTML---浮动

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.常见的网页布局 二.标准文档流 标准文档流常见标签 标准文档流的组成 块级元素<div…

青少年CTF-qsnctf-A1-Misc-签到

题目环境&#xff1a; 题目难度&#xff1a;★题目描述&#xff1a;有没有可能&#xff0c;这个平台就是个题目&#xff1f; 一道杂项题 题目说的是这个平台就是题目 那么也就是说flag就在这个平台里面1.从高层次向低层次逐一排查 2.首先对平台首页进行排查进平台首页 第一种解…

了解树和学习二叉树

1.树 1.1 概念 树是一种 非线性 的数据结构&#xff0c;它是由 n &#xff08; n>0 &#xff09;个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看 起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的 。 注意&#xff1a;树形结构中…

什么是数据资产化?数据怎样成为资产?怎样进入资产负债表?

财政部发布的《企业数据资源相关会计处理暂行规定》将从2024年1月1日起开始实施&#xff0c;为企业数据资源入表提供了基本指引&#xff0c;数据资产化有望迎来爆发期。什么是数据资产化&#xff0c;怎样让数据成为资产&#xff0c;成为了众多国有企业、上市公司关心的问题。 —…

「Vue3面试系列」Vue3.0性能提升主要是通过哪几方面体现的?

文章目录 一、编译阶段diff算法优化静态提升事件监听缓存SSR优化 二、源码体积三、响应式系统参考文献 一、编译阶段 回顾Vue2&#xff0c;我们知道每个组件实例都对应一个 watcher 实例&#xff0c;它会在组件渲染的过程中把用到的数据property记录为依赖&#xff0c;当依赖发…

C语言学习NO.10-指针(二)数组名的理解,使用指针访问数组,一维数组传参的本质,冒泡排序,二级指针,指针数组,指针数组模拟二维数组

一、数组名的理解 //使用指针访问数组的内容 int arr[10] {1,2,3,4,5,6,7,8,9,10}; int* p &arr[0]; 这里我们使用&arr[0]的方式拿到了数组第一个元素的地址&#xff0c;但是其实数组名本来就是地址&#xff0c;而且是数组首元素的地址。 #include <stdio.h>…