qustomplot的理解给出了QcustomPlot类的类图布局数据关系结束语
说明
这主要是介绍和理解QQ的总体实现思路非常重要。
QCustomPlot类
QCustomPlot类直接用于用户。 有默认的图层显示。
请参阅源代码。
qustomplot :3360 qcustomplot q构件*构件) : q构件parent )、xaxis0)、yAxis0) 0、xaxis2)0)、 yaxis 0mbufferdevicepixelratio 1.0 )、//willbeadaptedtoprimaryscreenbelowmplotlayout )、mautoaddplottabletolegend ) mantialiasedelements qcp :3360 AE none )、mnotantialiasedelements qcp :3360 AE none )、minteractions0)和ms elelectione moantialiasingondragfalse )、mbackgroundbrush ) Qt3360:white、Qt:SolidPattern )、 mbackgroundscaled ) true mbackgroundscaledmode Qt :3360 keepaspectratiobyexpanding )、mCurrentLayer0) 0、mplottinghinghion qcp:3360phimmediaterefresh ), mmultiselectmodifier ) Qt :3360控制模块mselectionrect模式qcp :3360 SRM none )、mselectionrect)、m OpenGL mouseeeventmode mousesignallayerable 0)、MRE plotting false )、mreplotqueued false )、mopenglmultisamples 16 ) )、 mopenglantialiaser mopenglcachelabelsbackup 真)集属性) Qt :3360 wa _ nomousepropagation; set attribute Qt :3360 wa _ opaquepaintevent; setfocus policy Qt :3360 click focus; 安全跟踪true; QLocale currentLocale=locale ; current locale.setnumberoptions qlocale :3360 omitgroupseparator; setlocale 当前本地; # ifdef qcp _ devicepixelratio _ supported # ifdef qcp _ devicepixelratio _ floatsetbufferdevicepixelratio # elsesetbufferated # endif # endifmopenglantialiasedelementsbackup=mantialiasedelements; mopenglcachelabelsbackup=mplottinghints.test flag qcp 33603360 phcachelabels ); //createinitiallayers 3360 m layers.append newqcplayer this,qlatin1string’background ‘ ) ) m layers.append newqccce m layers.append newqcplayer this,qLatin1string ) ‘ main ‘ ); m layers.append newqcplayer this,qlatin1string’axes ‘ ) ) m layers.append newqcplayer this,qlatin1string ) ) updateLayerIndices ; 设置层q latin1字符串)主); layerqlatin1string’overlay ‘ )-setmode ) QCplayer:3360lmbuffered );//创建initial layout,axis rect and
legend: mPlotLayout = new QCPLayoutGrid; mPlotLayout->initializeParentPlotthis); mPlotLayout->setParentthis); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry mPlotLayout->setLayerQLatin1String”main”)); QCPAxisRect *defaultAxisRect = new QCPAxisRectthis, true); mPlotLayout->addElement0, 0, defaultAxisRect); xAxis = defaultAxisRect->axisQCPAxis::atBottom); yAxis = defaultAxisRect->axisQCPAxis::atLeft); xAxis2 = defaultAxisRect->axisQCPAxis::atTop); yAxis2 = defaultAxisRect->axisQCPAxis::atRight); legend = new QCPLegend; legend->setVisiblefalse); defaultAxisRect->insetLayout)->addElementlegend, Qt::AlignRight|Qt::AlignTop); defaultAxisRect->insetLayout)->setMarginsQMargins12, 12, 12, 12)); defaultAxisRect->setLayerQLatin1String”background”)); xAxis->setLayerQLatin1String”axes”)); yAxis->setLayerQLatin1String”axes”)); xAxis2->setLayerQLatin1String”axes”)); yAxis2->setLayerQLatin1String”axes”)); xAxis->grid)->setLayerQLatin1String”grid”)); yAxis->grid)->setLayerQLatin1String”grid”)); xAxis2->grid)->setLayerQLatin1String”grid”)); yAxis2->grid)->setLayerQLatin1String”grid”)); legend->setLayerQLatin1String”legend”)); // create selection rect instance: mSelectionRect = new QCPSelectionRectthis); mSelectionRect->setLayerQLatin1String”overlay”)); setViewportrect)); // needs to be called after mPlotLayout has been created replotrpQueuedReplot);}
QcustomPlot类中包含其他功能模块,来进行布局和绘制。需要理解各个类的关系,其中QCPLayer类继承于QObject类。QCPLayout是布局的基类。各个图表的绘制建立在坐标轴之上,其中坐标轴的绘制建立在布局窗口之上,一个QCustomPlot可以有多个布局窗口,一个布局窗口可以包含多个样式坐标轴。
类图
QCPLayerable是所有可绘制对象的基类,包括网格,坐标轴,装饰器,图标。关于具体的实现可以参见官网例子。
布局
先上一张官网图片
其中最外层是顶层窗口的边缘,每个布局和相邻的窗口都有默认的间隔(每个布局都有自己的索引,布局中可以插入子布局),同样布局中的元素也有默认的间隔(每个元素都有自己的索引)。正是由于源码这种灵活的实现,使得我们可以在布局上有极大的自主权。
数据关系
说一下,它内部是如何实现的。每个图表都有自己对应的数据类:
比如QCPGraph内部维护着QCPGraghData的数组。当我们进行绘制的时候,取出其中的数据进行每个点的绘制。同样当我们想获取某个区域,或者某个像素点的的数据时,可以先进行像素点到坐标轴(参见QCPAxis类函数)的数据转换,然后通过相应图表的接口函数获取当前区域或者点的值。如下
QCPDataSelection selection = graph->selection); double sum = 0; foreach QCPDataRange dataRange, selection.dataRanges)) { QCPGraphDataContainer::const_iterator begin = graph->data)->atdataRange.begin)); // get range begin iterator from index QCPGraphDataContainer::const_iterator end = graph->data)->atdataRange.end)); // get range end iterator from index for QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it) { // iterator “it” will go through all selected data points, as an example, we calculate the value average sum += it->value; } } double average = sum/selection.dataPointCount);
获取选中区域的数据,首先要设置选中属性。这个逻辑可以写在鼠标弹起事件中。
QCPGraphDataContainer::const_iterator it = graph->data)->constEnd); QVariant details; if graph->selectTestQPoint123, 456), false, &details)) // QPoint could be e.g. event->pos) of a mouse event { QCPDataSelection dataPoints = details.value<QCPDataSelection>); if dataPoints.dataPointCount) > 0) it = graph->data)->atdataPoints.dataRange).begin)); } // iterator “it” now carries the data point at pixel coordinates 123, 456), or constEnd if no data point was hit.
这个逻辑可以写在鼠标点击事件和鼠标弹起事件中
结束语
如何想要绘制出比较好看的图,还是要图层元素的属性有详细的了解。
附上官网
文档