若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/128194710
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
上一篇:《Qwt开发笔记(一):Qwt简介、下载以及基础demo工程模板》
下一篇:敬请期待…
QWT开发笔记系列整理集合,这是目前使用最为广泛的Qt图表类(Qt的QWidget代码方向只有QtCharts,Qwt,QCustomPlot),使用多年,系统性的整理,本系列旨在系统解说并逐步更新其各种Demo示例
本片文章主要讲解折线图,借助折线图展现一个基础流程框架。
QwtPlot是一个用于绘制二维图形的小部件。画布上可以显示无限数量的绘图项目。绘图项目可以是曲线(QwtPlotCurve)、标记(QwtPlotMarker)、网格(QwtPrintGrid)或从QwtPlotItem派生的任何其他内容。一个绘图最多可以有四个轴,每个绘图项目都连接到一个x轴和一个y轴。轴上的比例可以显式设置(QwtScaleDiv),或使用算法(QwtScale Engine)根据绘图项计算,该算法可以为每个轴单独配置。
此枚举描述图表中启用的动画。
bool QwtPlot::autoReplot () const
如果设置了autoReplot选项,则为true。
bool QwtPlot::axisAutoScale(QwtAxisId axisId) const
如果启用了自动缩放,则为true。
QFont QwtPlot::axisFont (QwtAxisId axisId) const
返回指定轴刻度的字体。
QwtInterval QwtPlot::axisInterval(QwtAxisId axisId) const
返回指定轴的当前间隔。同axiscaleDiv(axisId)->interval()类似。
int QwtPlot::axisMaxMajor(QwtAxisId axisId) const
指定轴的最大主刻度数。
int QwtPlot::axisMaxMinor (QwtAxisId axisId) const
指定轴的最大次刻度数。
const QwtScaleDiv & QwtPlot::axisScaleDiv(QwtAxisId axisId) const
返回指定轴的比例分割。
axiscaleDiv(axisId).lowerBound()和axiscaleDiv(axisId).upperBound()是轴比例的当前限制。
QwtScaleDraw * QwtPlot::axisScaleDraw(QwtAxisId axisId)
const QwtScaleDraw * QwtPlot::axisScaleDraw (QwtAxisId axisId) const
返回指定轴的比例绘制。
QwtScaleEngine * QwtPlot::axisScaleEngine(QwtAxisId axisId)
const QwtScaleEngine * QwtPlot::axisScaleEngine(QwtAxisId axisId) const
返回轴的缩放引擎
double QwtPlot::axisStepSize(QwtAxisId axisId) const
返回在setAxisScale中设置的步长参数。这不一定是当前比例的步长。
QwtText QwtPlot::axisTitle(QwtAxisId axisId) const
QwtScaleWidget * QwtPlot::axisWidget(QwtAxisId axisId)
const QwtScaleWidget * QwtPlot::axisWidget(QwtAxisId axisId) const
指定轴的缩放控件,如果axisId无效,则为NULL。
QBrush QwtPlot::canvasBackground() const
绘图区域的背景画笔。
QwtScaleMap QwtPlot::canvasMap(QwtAxisId axisId) const virtual
返回画布上轴的贴图。使用该贴图,像素坐标可以转换为绘图坐标,反之亦然。
void QwtPlot::drawCanvas(QPainter * painter) virtual
重新绘制画布。drawCanvas调用同样用于打印的drawItems。喜欢添加单个绘图项的应用程序更好地重载drawItems()。
void QwtPlot::drawItems(QPainter * painter, const QRectF &canvasRect,const QwtScaleMap maps[QwtAxis::AxisPositions]) const virtual
通常canvasRect是绘图画布的contentsRect()。由于Qt中的错误,此矩形对于某些框架样式(例如QFrame::Box)可能是错误的,可能需要使用QWidget::setContentsMargins()手动修复边距
QwtText QwtPlot::footer() const
页脚文本
QwtTextLabel * QwtPlot::footerLabel()
const QwtTextLabel * QwtPlot::footerLabel() const
页脚标签小部件。
void QwtPlot::getCanvasMarginsHint(const QwtScaleMap maps[], const QRectF & canvasRect, double & left, double & top, double & right, double & bottom) const virtual
计算画布边距。
void QwtPlot::insertLegend(QwtAbstractLegend * legend,QwtPlot::LegendPosition pos = wtPlot::RightLegend, double ratio = -1.0)
插入图例。
如果位置图例是QwtPlot::LeftLegend或QwtPlot::RightLegend,则图例将从上到下组织在一列中。否则,图例项将放置在从左到右具有最佳列数的表中。
insertLegend()将把绘图小部件设置为图例的父项。图例将在绘图的析构函数中删除,或在插入另一个图例时删除。
未插入绘图小部件布局的图例需要连接到legendDataChanged()信号。调用updateLegend()将为初始更新启动此信号。当应用程序代码想要实现自己的布局时,也需要将绘图渲染到文档中。
double QwtPlot::invTransform(QwtAxisId axisId, double pos ) const
将绘图区域中位置的x或y坐标转换为值。
bool QwtPlot::isAxisValid (QwtAxisId axisId) const
bool isAxisVisible (QwtAxisId) const
void QwtPlot::replot() virtual slot
绘制坐标网格的类。
QwtPlotGrid类可用于绘制坐标网格。坐标轴网由主要和次要的垂直和水平轴网线组成。网格线的位置由X和Y比例划分确定,可以使用setXDiv()和setYDiv()指定。draw()成员在边界矩形内绘制网格。
void QwtPlotGrid::enableX(bool on)
void QwtPlotGrid::enableY(bool on)
void QwtPlotGrid::enableXMin(bool on)
void QwtPlotGrid::enableYMin(bool on)
const QPen & QwtPlotGrid::majorPen() const
const QPen & QwtPlotGrid::minorPen() const
图例小部件。
QwtLegend小部件是图例项的表格排列。图例项可以是任何类型的小部件,但通常它们都是QwtLegendLabel。
可设置只显示、显示可选择,显示可点击并抛出对应的信号。
使用时,直接new即可,没啥可说的。
用于绘制符号的类,作用于实际数据点。
void QwtSymbol::setStyle (QwtSymbol::Style style)
void QwtSymbol::setSize(const QSize & size)
void QwtSymbol::setSize(int width, int height = -1)
指定符号的大小。
如果“h”参数被忽略或小于0,而“w”参数大于或等于0,则符号大小将设置为(w,w)。
(注意:本文只列Demo举用到的,下一篇文章将会着重讲解QwtPlotCurve类)
表示一系列点的绘图项。
曲线是x-y平面中一系列点的表示。它支持不同的显示样式、插值(例如样条曲线)和符号。
创建曲线时,将配置为使用QwtPlotCurve::lines样式绘制黑色实线,而不使用符号。您可以通过调用setPen()、setStyle()和setSymbol()来更改此符号,使用QwtSymbol类来实现。
QwtPlotCurve使用QwtSeriesData对象获取其点,该对象为点的实际存储提供桥梁(如QAbstractItemModel)。
有几个从QwtSeriesData派生的便利类,它们也在内部存储点(如QStandardItemModel)。
QwtPlotCurve还提供了setSamples()的一些变体,它们从内部数组构建QwtSeriesData对象。
将QwtPlotItem附加到QwtPlot。它将首先将QwtPlotItem从任何绘图中分离出来(如果需要)。如果传递了NULL参数,它将从它所附加的任何QwtPlot分离。(可以判断出,它只能附属一个绘图)
void QwtPlotItem::setTitle(const QString & title)
void QwtPlotItem::setTitle(const QwtText & title)
void QwtPlotCurve::setPen(const QColor & color,qreal width = 0.0,Qt::PenStyle style = Qt::SolidLine)
void QwtPlotCurve::setPen(const QPen & pen)
指定画笔,宽度,线型等。
void QwtPlotItem::setXAxis(QwtAxisId axisId)
该项目将根据其坐标轴绘制。
void QwtPlotItem::setYAxis(QwtAxisId axisId)
该项目将根据其坐标轴绘制。
void QwtGraphic::setRenderHint(RenderHint hint,bool on = true);
只能设置QwtPlotItem::RenderAntialiased,然后参数为开启或者关闭。
void QwtPlotCurve::setSamples(const QVector< double > & xData,const QVector< double > & yData)
使用x和y数组初始化数据(显式共享)。
void QwtPlotCurve::setSamples(const double * xData,const double * yData,int size)
通过从指定的内存块复制x和y值来设置数据。与setRawSamples()相反,此函数生成数据的“深度副本”。
void QwtPlotItem::attach(QwtPlot * plot)
将项目附着到绘图。
此方法将QwtPlotItem附加到QwtPlot参数。它将首先将QwtPlotItem从任何绘图中分离出来(如果需要)。如果传递了NULL参数,它将从它所附加的任何QwtPlot分离。
#ifndef LINECHARTWIDGET_H
#define LINECHARTWIDGET_H#include
#include #include "qwt.h"
#include "qwt_plot.h"
#include "qwt_plot_grid.h"
#include "qwt_legend.h"
#include "qwt_plot_curve.h"
#include "qwt_symbol.h"
#include "qwt_spline_curve_fitter.h"namespace Ui {
class LineChartWidget;
}class LineChartWidget : public QWidget
{Q_OBJECTpublic:explicit LineChartWidget(QWidget *parent = 0);~LineChartWidget();public:QColor getBackgroundColor() const;public:void setBackgroundColor(const QColor &backgroundColor);protected:void initControl();void initQwtPlot();protected slots:void slot_addDataTimeOut();protected:void resizeEvent(QResizeEvent *event);void timerEvent(QTimerEvent *event);private:Ui::LineChartWidget *ui;private:int _timerId;qint64 _startTime; // 启动时间private:QColor _backgroundColor; // 背景颜色private:QwtPlot *_pQwtPlot; // qwt图QwtPlotGrid *_pGrid; // 虚线框QwtLegend *_pLegend; // 图例QwtPlotCurve *_pCurve1; // 曲线1QwtSymbol *_pSymbol1; // 曲线1点符号QwtPlotCurve *_pCurve2; // 曲线2QVector _vectorX1; // 曲线1缓存数据QVector _vectorY1; // 曲线1缓存数据QVector _vectorX2; // 曲线2缓存数据QVector _vectorY2; // 曲线2缓存数据double _rangeX; // 范围QTimer *_pTimerAddData; // 添加数据定时器
};#endif // LINECHARTWIDGET_H
#include "LineChartWidget.h"
#include "ui_LineChartWidget.h"#include
#include
//#define LOG qDebug()<<__FILE__<<__LINE__
//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__
//#define LOG qDebug()<<__FILE__<<__LINE__<ui->setupUi(this);// 背景透明,在界面构架时,若为本窗口为其他窗口提升为本窗口时,// 则再qss会在主窗口第一级添加frame_all,防止其他窗口提升本窗口而冲掉qss设置
// setWindowFlag(Qt::FramelessWindowHint);
// setAttribute(Qt::WA_TranslucentBackground, true);initControl();initQwtPlot();_startTime = QDateTime::currentDateTime().toMSecsSinceEpoch();_timerId = startTimer(16);timerEvent(0);
}LineChartWidget::~LineChartWidget()
{delete ui;
}void LineChartWidget::initControl()
{_pTimerAddData = new QTimer(this);connect(_pTimerAddData, SIGNAL(timeout()),this, SLOT(slot_addDataTimeOut()));_pTimerAddData->setInterval(1000);_pTimerAddData->start();
}void LineChartWidget::initQwtPlot()
{_pQwtPlot = new QwtPlot(this);// 设置背景色_pQwtPlot->setCanvasBackground(QBrush(QColor(255, 255, 255)));// 设置x1坐标轴{_pQwtPlot->setAxisTitle(QwtPlot::xBottom, "x");_pQwtPlot->setAxisAutoScale(QwtPlot::xBottom, true);}// 设置y1坐标轴{_pQwtPlot->setAxisTitle(QwtPlot::yLeft, "y");_pQwtPlot->setAxisAutoScale(QwtPlot::yLeft, true);}// 设置y2坐标轴{_pQwtPlot->setAxisTitle(QwtPlot::yRight, "y");_pQwtPlot->setAxisVisible(QwtPlot::yRight, true);_pQwtPlot->setAxisAutoScale(QwtPlot::yRight, true);}// 设置绘图区域网格{_pGrid = new QwtPlotGrid();_pGrid->setMajorPen(Qt::gray, 1, Qt::SolidLine);_pGrid->attach(_pQwtPlot);}// 设置图例{_pLegend = new QwtLegend();_pLegend->setDefaultItemMode(QwtLegendData::ReadOnly);_pQwtPlot->insertLegend(_pLegend);}// 设置曲线1{_pCurve1 = new QwtPlotCurve();_pCurve1->setTitle("y1");_pCurve1->setPen(Qt::blue, 1);_pCurve1->setRenderHint(QwtPlotItem::RenderAntialiased, true);// 关联轴_pCurve1->setXAxis(QwtPlot::xBottom);_pCurve1->setYAxis(QwtPlot::yLeft);}// 曲1符号对象{_pSymbol1 = new QwtSymbol(QwtSymbol::Ellipse);_pSymbol1->setPen(Qt::red);_pSymbol1->setBrush(Qt::red);_pSymbol1->setSize(2);_pCurve1->setSymbol(_pSymbol1);}// 曲线1数据{// 这是采用显示共享的方式_pCurve1->setSamples(_vectorX1, _vectorY1);// 将曲线添加到绘图_pCurve1->attach(_pQwtPlot);}// 曲线2{_pCurve2 = new QwtPlotCurve();_pCurve2->setTitle("y2");_pCurve2->setPen(Qt::red, 1);_pCurve2->setRenderHint(QwtPlotItem::RenderAntialiased, true);// 关联轴_pCurve2->setXAxis(QwtPlot::xBottom);_pCurve2->setYAxis(QwtPlot::yRight);}// 曲线2数据{// 这是采用显示共享的方式_pCurve2->setSamples(_vectorX2, _vectorY2);// 将曲线添加到绘图_pCurve2->attach(_pQwtPlot);}}void LineChartWidget::slot_addDataTimeOut()
{// 计算时间double currentTime = QDateTime::currentDateTime().toMSecsSinceEpoch();currentTime -= _startTime;currentTime /= 1000;// 添加曲线1数据_vectorX1.append(currentTime);_vectorY1.append(qrand() % 20 - 10);// 添加曲线2数据_vectorX2.append(currentTime);_vectorY2.append(qrand() % 50);// 数据置换(不知换数据进不去,显示共享无效?)_pCurve1->setSamples(_vectorX1, _vectorY1);_pCurve2->setSamples(_vectorX2, _vectorY2);
}void LineChartWidget::resizeEvent(QResizeEvent *event)
{if(_pQwtPlot){_pQwtPlot->setGeometry(rect());}QWidget::resizeEvent(event);
}void LineChartWidget::timerEvent(QTimerEvent *event)
{// 计算时间double currentTime = QDateTime::currentDateTime().toMSecsSinceEpoch();currentTime -= _startTime;currentTime /= 1000;if(currentTime < 10.0){_pQwtPlot->setAxisScale(QwtPlot::xBottom, 0, _rangeX, 1);}else{_pQwtPlot->setAxisScale(QwtPlot::xBottom, currentTime - _rangeX, currentTime, 1);}_pQwtPlot->replot();
}QColor LineChartWidget::getBackgroundColor() const
{return _backgroundColor;
}void LineChartWidget::setBackgroundColor(const QColor &backgroundColor)
{_backgroundColor = backgroundColor;
}
显示共享理解为共用数据,但是数据不绘制到图。
查看曲线是否有更新数据到图的实现,是没有的。
直接设置可刷新数据
直接setSample一次来解决。
上一篇:《Qwt开发笔记(一):Qwt简介、下载以及基础demo工程模板》
下一篇:敬请期待…