当前位置: 首页 > news >正文

QChart绘制折线图

这一篇我们详细介绍图表各个部分的设置和操作,包括图表的标题、图例、边距等属性设置,QLineSeries序列的属性设置,QValueAxis坐标轴的属性设置,以及图标的缩放。(这些应该都是在实际的Qt开发中比较常用的图表操作)先看运行时的界面:

https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/20240824221403.png

界面设计

  • 工具栏:创建几个Action,并创建工具栏,实现图表数据刷新和缩放功能。

  • 主工作区图标视图:从组件面板放置一个QGraphics View组件作为视图组件,并用Promote方法升级为QChartView组件,命名为chartView

  • 图表属性设置面板:左侧是一个QToolBox组件,分为3个操作面板,用于进行图表设置、曲线设置和坐标轴设置。

https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/20240824215739.png

https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/20240824215810.png

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

主窗口类的定义和初始化

下面是主窗口类MainWindow的类定义(省略了Action和界面组件的槽函数定义)。在mainwindow.h文件重需要包含QtChart,并使用宏QT_CHARTS_USE_NAMESPACE导入命名空间。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QtCharts>
QT_CHARTS_USE_NAMESPACE
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:QLineSeries* curSeries; // 当前序列QValueAxis* curAxis; // 当前坐标轴void createChart(); // 创建图表void prepareData(); // 更新数据void updateFromChart(); // 从图表更新到界面private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

MainWindow类中定义了两个私有的变量,curSeries用于指向当前的QLineSeries序列,界面上对序列的设置操作都是针对当前选择的序列;curAxis用于指向当前的QValueAxis坐标轴,对坐标轴进行设置时就是针对当前坐标轴进行设置。

createChart()函数用于创建图表的各个基本部件,在构造函数里调用,prepareData()用于更新序列的数据,updateFormChart()用于读取图表的一些属性,并刷新界面显示。下面是主窗口构造函数,以及这3个函数的代码。

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);createChart(); // 创建图表prepareData(); // 生成数据updateFromChart(); // 从图表获取属性值,刷新到界面显示
}void MainWindow::createChart()
{QChart* chart = new QChart();chart->setTitle("简单函数曲线");ui->chartView->setChart(chart);ui->chartView->setRenderHint(QPainter::Antialiasing); // 抗锯齿,平滑QLineSeries* series0 = new QLineSeries();QLineSeries* series1 = new QLineSeries();series0->setName("Sin 曲线");series1->setName("Cos 曲线");curSeries = series0;QPen pen;pen.setStyle(Qt::DotLine);pen.setWidth(2);pen.setColor(Qt::red);series0->setPen(pen);pen.setStyle(Qt::SolidLine);pen.setColor(Qt::blue);series1->setPen(pen);chart->addSeries(series0);chart->addSeries(series1);QValueAxis* axisX = new QValueAxis();curAxis = axisX;axisX->setRange(0, 10);axisX->setLabelFormat("%.1f"); // 标签格式axisX->setTickCount(11); // 主分隔个数axisX->setMinorTickCount(9); // 次分隔个数axisX->setTitleText("time(secs)"); // 标题QValueAxis* axisY = new QValueAxis();axisY->setRange(-2, 2);axisY->setTitleText("value");axisY->setTickCount(5);axisY->setLabelFormat("%.2f");axisY->setMinorTickCount(4);chart->setAxisX(axisX, series0);chart->setAxisY(axisY, series0);chart->setAxisX(axisX, series1);chart->setAxisY(axisY, series1);
}void MainWindow::prepareData()
{QLineSeries* series0 = (QLineSeries*)ui->chartView->chart()->series().at(0);QLineSeries* series1 = (QLineSeries*)ui->chartView->chart()->series().at(1);series0->clear();series1->clear();qsrand(QTime::currentTime().second()); // 初始化随机数qreal t = 0;qreal y1, y2;qreal intv = 0.1;qreal rd;int cnt = 100;for (int i = 0; i < cnt; i++) {rd = (qrand() % 10) - 5;y1 = qSin(t) + rd / 50;series0->append(t, y1);rd = (qrand() % 10) - 5;y2 = qCos(t) + rd / 50;series1->append(t, y2);t += intv;}
}void MainWindow::updateFromChart()
{QChart* chart = ui->chartView->chart();ui->editTitle->setText(chart->title());QMargins mg = chart->margins(); // 边距ui->spinMarginTop->setValue(mg.top());ui->spinMarginLeft->setValue(mg.left());ui->spinMarginRight->setValue(mg.right());ui->spinMarginBottom->setValue(mg.bottom());
}
  • MainWindow类个构造函数调用单个私有函数进行图表和界面的初始化。

  • createChart()函数用于创建QChart对象,创建数据序列和坐标轴,并将这些部件组合成一个完整的图表。

  • prepareDate()函数用于为图表重的两个序列生成数据,其中使用随机数,以便使得每次生成的数据稍有不同。

  • updateFromChart()函数用于将图表重的标题和边距信息显示到窗口界面上。

笔画设置对话框QWDialogPen

在这个demo中,需要设置一些对象的pen属性,比如折线序列的pen属性,网络先的pen属性等。pen属性其实就是一个QPen对象,设置内容主要包括线型,线宽和颜色。为了使用方便,设计一个自定义对话框QWDialogPen,专门用于QPen对象的属性设置。

https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/20240825033758.png

QWDialogPen是一个可视化设计的对话框,其类型定义如下:

class QWDialogPen : public QDialog
{Q_OBJECTpublic:explicit QWDialogPen(QWidget *parent = nullptr);~QWDialogPen();void setPen(QPen pen); // 设置Qpen,用于对话框界面显示QPen getPen(); // 获取对话框设置的QPen属性static QPen getPen(QPen iniPen, bool& ok); //静态函数private slots:void on_btnColor_clicked();private:Ui::QWDialogPen *ui;QPen m_pen;
};

QWDialogPen类的getPen()以及相关函数的实现代码如下:

void QWDialogPen::setPen(QPen pen)
{m_pen = pen;ui->spinWidth->setValue(pen.width());int i = static_cast<int>(pen.style());ui->comboPenStyle->setCurrentIndex(i);QColor color = pen.color();ui->btnColor->setAutoFillBackground(true);QString str = QString::asprintf("background-color: rgb(%d,%d,%d);", color.red(), color.green(), color.blue());ui->btnColor->setStyleSheet(str);
}QPen QWDialogPen::getPen()
{m_pen.setStyle(Qt::PenStyle(ui->comboPenStyle->currentIndex()));m_pen.setWidth(ui->spinWidth->value());QColor color = ui->btnColor->palette().color(QPalette::Button);m_pen.setColor(color);return m_pen;
}QPen QWDialogPen::getPen(QPen iniPen, bool &ok)
{QWDialogPen* dlg = new QWDialogPen();dlg->setPen(iniPen);QPen pen;int ret = dlg->exec(); // 弹出对话框if (ret == QDialog::Accepted) {pen = dlg->getPen(); // 获取ok = true;}else {pen = iniPen;ok = false;}delete dlg; // 删除对话框对象return pen; //返回设置的QPen对象
}

静态函数getPen()里创建了一个QWDialogPen类的实例dlg,然后调用dlg→setPen(iniPen)进行初始化,运行对话框并获取返回值,若返回值为QDialog::Accepted,就调用dlg→getPen()获取设置属性后的QPen对象,最后删除对话框对象并返回设置的Qpen对象。所以,静态函数getPen()就是集成了普通方法调用对话框时创建对话框,设置初始值、获取对话框返回状态、获取返回删除对话框的过程,简化了调用代码。

QChart设置

QChart类的主要函数

分组函数名功能描述
图表外观void setTitle()设置图表标题,支持HTML
void setTitleFont()设置图表标题字体
void setTitleBrush()设置比图表标题画刷
void setTheme()设置主题,定义了图表的配色
void setMargins()设置绘图区与图表边界的四个边距
QLegend* legend()返回图表的图例,是一个QLegend类对象
void setAnimationOptions()设置序列或坐标轴的动画效果
数据序列void addSeries()添加序列
QList<QAbstractSeries*>series()返回图表拥有的序列的列表
void removeSeries()移除一个序列,但并不删除序列对象
void removeAllSeries()移除并删除图表的所有序列
坐标轴void addAxis()为图表的某个方向添加坐标轴
QList<QAbstractSeries*> axes()返回某个方向的坐标轴列表
void setAxisX()设置某个序列的水平方向的坐标轴
void setAxisY()设置某个序列的垂直方向的坐标轴
void removeAxis()移除一个坐标轴
void createDefaultAxes()更具已添加的序列类型,创建缺省的坐标轴,前面已有的坐标轴会被删除

通过图表的设置界面可以设置标题的内容和字体,可以设置图例的位置,是否显示,字体颜色和边距;可以设置动画效果和主题。

https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/20240825194552.png

https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/20240825194609.png

setAnimationOptions(AnimationOptions options)函数设置图表的动画效果,输入参数是QChart::AnimationOption枚举类型,有以下取值:

  • QChart::NoAnimation:无动画效果;

  • QChart::GridAxisAnimations:背景网格有动画;

  • QChart::SeriesAnimations:序列有动画效果;

  • QChart::AllAnimations:都有动画效果。

主题是预定义的图表配色样式,是QChart::ChartTheme枚举类型,有多种取值。

图例是一个QLegend类对象,通过QChart::legend()可以获取图表的图例。图例是根据添加的序列自动生成的,但是可以修改一些属性,如:位置,文字和字体等。例如:

ui->chartView->chart()->legend()->setAlignment(Qt::AlignBottom);void MainWindows::on_btnLegendFont_clicked() {QFont font = ui->chartView->chart()->legend()->font();bool ok = false;font = QFontDialog::getFont(&ok, font);if (ok) {ui->chartView->chart()->legend()->setFont(font);}
}

http://www.mrgr.cn/news/8973.html

相关文章:

  • 【C++】函数模板特化:深度解析与应用场景
  • 【设计模式】模块模式和桥接模式
  • Android笔试面试题AI答之Kotlin(18)
  • postgresql 使用explain 进行SQL分析
  • ios白苹果修复办法有哪些?
  • 【微服务】springboot整合对象映射工具MapStruct使用详解
  • nginx做代理 转发前端请求到后端
  • 698. 划分为k个相等的子集
  • java日常管理
  • 如何使用 vue2+element-ui 处理复杂表单,避免单文件过大的问题
  • Android14 以太网共享功能 相关代码简介
  • Lumos学习王佩丰Excel第十四讲:日期函数
  • Tailwind CSS的介绍和使用
  • (十)Flink Table API 和 SQL 基本概念
  • 数据库的读写分离技术MVCC
  • 线性代数 第二讲 矩阵_逆矩阵_伴随矩阵_分块矩阵_初等矩阵_矩阵的秩
  • c语言利用switch多路开关制作输入月份判断季节的程序
  • Python如何实现PPT演示文稿到图片的批量转换
  • 【AI】阿里云AI开发平台PAI:构建智能未来
  • 每日Attention学习16——Multi-layer Multi-scale Dilated Convolution