文章首发自公众号:: nullobject 。
我的站点: https://www.nullobject.cn
这篇文章主要介绍QXYSeries类的API及其使用
QXYSeries
做为QAbstractSeries的派生类之一,主要负责实现以二维点集为数据源,坐标类型为二维坐标系的图表类型,包括折线图、曲线图和散点图等。QXYSeries封装了大量对数据源进行增删改操做的函数和信号,同时内部实现了控制数据点在坐标系上的显示形态(点标签的格式、颜色、是否显示等)的功能。html
Qt图表中的点标签指的是数据点在图表上对应位置的附加信息显示(好比点的坐标或者其余信息):数据结构
QXYSeries类中提供了pointLabels*开头的五个属性及对应的方法和信号来操做点标签的显示风格。app
bool pointLabelsClipping() const; void setPointLabelsClipping(bool enabled = true);
效果:函数
能够看到,当设置pointLabelsClipping
属性为true(默认值)时,点标签超出绘图区域的部分会被裁剪掉。性能
pointLabelsClipping属性发生改变时,会触发 pointLabelsClippingChanged(bool clipping)信号。
QColor pointLabelsColor() const; void setPointLabelsColor(const QColor &color);
效果:字体
上图分别为将pointLabelsColor属性设置为黑色和绿色的效果。看到这您有可能会有疑问:咦怎么只改变了坐标的颜色,而折线上点的颜色没有变?注意了,这里的点标签是指图表上对数据点加以说明的信息部分,不包括点自己的显示。spa
pointLabelsColor属性发生改变时,会触发 pointLabelsColorChanged(const QColor &color)信号。
QFont pointLabelsFont() const; void setPointLabelsFont(const QFont &font);
该属性经过一个QFont设置来实现:code
// 获取pointLabels默认字体 QFont font = series->pointLabelsFont(); // 加粗 font.setBold(true); // 斜体 font.setItalic(true); // 设置字体大小 font.setPointSize(12); // 设置字体为Arial类型 font.setFamily(QStringLiteral("Arial")); // 更新pointLabels字体 series->setPointLabelsFont(font);
效果:orm
pointLabelsFont属性发生改变时,会触发 pointLabelsFontChanged(const QFont &font)信号。
QString pointLabelsFormat() const; void setPointLabelsFormat(const QString &format);
QXYSeries类提供了两个占位符来设置点标签显示真实坐标数据:htm
@xPoint | X轴坐标 |
---|---|
@yPoint | Y轴坐标 |
例如,咱们须要以:(15,23)
这样的格式来显示点标签,能够这样设置,便可实现上文中点标签的显示格式效果:
// 设置点标签格式 series->setPointLabelsFormat(QStringLiteral("(@xPoint,@yPoint)"));
pointLabelFormat属性默认被设置为没有括号的坐标格式:@xPoint, @yPoint
。
pointLabelsFormat属性发生改变时,会触发 pointLabelsFormatChanged(const QString &format)信号。
bool pointLabelsVisible() const; void setPointLabelsVisible(bool visible=true);
该属性默认被设置为false。
// 隐藏点标签 series->setPointLabelsVisible(false);
效果:
pointLabelsVisible属性发生改变时,会触发 pointLabelsVisibilityChanged(bool visible)信号。
bool pointsVisible() const; void setPointsVisible(bool visible=true);
与 pointsLabelVisible不一样,pointsLabelVisible设置的是 点标签的显示,而 pointsVisible设置的是 点自己在图表上的位置标注。
该属性默认被设置为false。对比显示和隐藏点标注效果:
QXYSeries
类中封装了一系列的重载方法用于操做图表的数据源进行增删改。QXYSeries内部用一个模板类型为QPointF
的QVector来持有数据源,其声明在qxyseries_p.h
头文件内:
能够调用append
的对应重载方法,或者是重载操做符<<
添加单个点或者整个点集到数据源的尾部:
void append(qreal x, qreal y); void append(const QPointF &point); void append(const QList<QPointF> &points);
QXYSeries& operator<<(const QPointF &point); QXYSeries& operator<<(const QList<QPointF> &points);
也能够调用insert
方法将数据点插入到数据源的指定位置:
void insert(int index, const QPointF &point);
对应地,无论以何种方式,成功添加数据后都会触发pointAdded(int index)
信号,index为被添加的数据的下标。须要注意:每添加一个点就会触发一次pointAdded信号,即批量添加数据时会触发对应次数的pointAdded。
QXYSeries提供了remove
重载方法和removePoints
方法来移除目标数据:
// 删除指定坐标的点 void remove(qreal x, qreal y); void remove(const QPointF &point); // 删除指定索引下标的点 void remove(int index); // 从下标index位置开始,删除count数量的点 void removePoints(int index, int count);
与增长数据相似,成功删除数据后会触发对应次数的pointRemoved(int index)
信号,index为被删除的数据的下标。
修改数据源经过replace
系列的重载方法实现:
// 替换具体坐标的点 void replace(qreal oldX, qreal oldY, qreal newX, qreal newY); void replace(const QPointF &oldPoint, const QPointF &newPoint); // 替换指定索引下标的点 void replace(int index, qreal newX, qreal newY); void replace(int index, const QPointF &newPoint); // 替换整个数据源 void replace(QList<QPointF> points); void replace(QVector<QPointF> points);
当只替换数据源的局部数据点(调用前四种重载方法)时,会触发pointReplaced(int index)
信号,index为被替换的点的下标;而当替换了整个数据源数据(调用后两种方法)时,则会触发pointsReplaced()
信号。
须要注意:调用replace
后两种重载替换整个数据源时,传QList仍是传QVector在性能上是有所区别的:直接传入QList结构的数据集远远比逐个点替换或者先清除全部点再添加这两种方式的效率要高。而直接传入QVector结构的数据集又比前者效率要高。所以:须要批量更新数据点时,应当优先选择void replace(QVector<QPointF> points);
这个重载方法。究其缘由:本小节一开始就介绍了,QXYSeries内部持有数据源的数据结构为QVector<QPointF>
,而参数为QList<QPointF>
的重载方法的内部实现也是将QList转换为QVector,再调用参数为QVector<QPointF>
的重载方法实现对数据的更新,无形中多了一个数据转换的步骤,拉低性能:
Tips:QList和QVector两个容器自己的效率上也是有区别的,Qt官方推荐优先使用QVector。详细能够参考QVector的官方文档介绍。
QXYseries提供了返回类型分别为QList<QPointF>
和QVector<QPointF>
的方法获取数据源:
QList<QPointF> points() const; QVector<QPointF> pointsVector() const;
与更新replace方法批量更新数据源的重载相似,points()
方法获取数据源的方法,内部实现也是获取原始数据源再将其转为QList类型返回;pointsVector()
方法则直接返回原始的QVector数据源。
QXYSeries共提供了五个鼠标事件响应信号,分别是:单击clicked
、双击doubleClicked
、鼠标键按下pressed
,鼠标键松开released
、光标移到图表线上或从图表移开hovered
:
series->connect(series,&QLineSeries::clicked,[](const QPointF& point){ qDebug() << "point clicked:" << point; }); series->connect(series,&QLineSeries::doubleClicked,[](const QPointF& point){ qDebug() << "point double clicked:" << point; }); series->connect(series,&QLineSeries::hovered,[](const QPointF& point,bool state){ qDebug() << "point hovered:" << point << " state:" << (state?"光标移动到图表上":"光标从图表上移开"); }); series->connect(series,&QLineSeries::pressed,[](const QPointF& point){ qDebug() << "point pressed:" << point; }); series->connect(series,&QLineSeries::released,[](const QPointF& point){ qDebug() << "point released:" << point; });
运行程序,执行光标移动到图表序列上->左键双击->光标从图表序列上方移开,结果以下:
point hovered: QPointF(4.58291,8.71473) state: moved to series point pressed: QPointF(4.58291,8.71473) point released: QPointF(4.58291,8.71473) point clicked: QPointF(4.58291,8.71473) point double clicked: QPointF(4.58291,8.71473) point pressed: QPointF(4.58291,8.71473) point released: QPointF(4.58291,8.71473) point clicked: QPointF(4.58291,8.71473) point hovered: QPointF(4.71022,8.18182) state: moved from series