https://download.csdn.net/download/qq_20088499/10720690
俗话说的好,不上图说个JB。来!动图。
QCustomPlot的普通画线,我将折线花在了QLabel里面,
你也可以重载其他控件,或者直接画在主界面上。
下面是在另一个图层layer上的绘图。
最近在写一个辅助性的平台软件,基本功能是将矢量数据更直观的表现出来,就是画线呗,折线。领导让最大化的尽可能的完善一下,超越他之前的版本,看多代码之后觉得使用的框架不是很方便,Qt自己封装的一个框架。所以我就要寻找一个更方便的框架,其实对于我们大拿们来讲,他们更加热衷于底层,探讨中他们说越是贴近底层问题越少,约容易掌控,更倾向于自己从底层写。对于非大拿,我还是抱着试试看的态度去度娘搜一波关于这方面的第三方库。最后QCustomPlot被选中。官网中可以下载。这里使用的应该是2.0版本,时间长了,而且中途换过版本记不太清了。
官网地址:https://www.qcustomplot.com/
使用中发现,效率方面,同时画包含13000个点的折线缩放移动是明显卡顿,单条13000个点添加填充是卡顿也很明显,这只是单方面的测试数据,很多时候用不上这么大的数据量。
其中一些比较常用的功能比如:设置坐标轴的范围,坐标字体,刻度线的长短,刻度间距,坐标轴的最大值最小值,设置折线样式,这些都很容易找到,在demo代码里面都有用到,注释已标明。
官网的实例可以多研究研究,会给你很多启发,实例代码也可以利用。
在实现图一功能的时候,因为对QCustomPlot不熟悉走了很多弯路,也请教了一些人,本来想是不是自带这类的接口,后来在写实验demo的时候faod搞定。现在想来其实很简单,思路就是:在移动Label1中的折线时利用connect,槽函数中同时设置其他两条线的横竖坐标轴的取值范围和Label1中的一致,既解决了。
纵坐标左侧的小方块跟踪,用到QCPAxis这个类。
具体实现在demo代码里面有。
图二中的折线其实并不是原始的折线,而是将原始的折线隐藏了再重新画上去的线,并不是一开始的添加点再连线。这里就用到了一个方法,QCustomPlot在另一个图层上绘图。
经过查找资料,最终我理解为QCustomPlot可以有好多个图层,原始折线是在基本图层上,而在任意其他图层上就可以通过重载void draw(QCPPainter *painter);函数来进行绘制。
具体方法:
重写一个继承自QCPLayerable的类,然后重载draw(),设置图层显示,设置QCustomPlot的画笔,切记不是普通的QPainter,而是QCPPainter。
class Layer : public QCPLayerable
{
Q_OBJECT
public:
Layer(QCustomPlot *plot);
~Layer();
QCPPainter *mpainter;
QCPLayer *layer;
bool visible;
QPoint movep;
QString LayerName() const;
void setVisible_(bool visible); //设置层是否绘制
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const{};
virtual void draw(QCPPainter *painter);
// void mousePressEvent(QMouseEvent *event, const QVariant &details);
public slots:
void Mousepressevent(QMouseEvent *event);
void MouseMoveEvent(QMouseEvent *event);
void getvalue(int x);
private:
// QScopedPointer ptr;
};
要在构造函数中将图层添加到QCustomPlot中
Layer::Layer(QCustomPlot *plot) : QCPLayerable(plot)
// ,ptr(new layerprivate)
{
mpainter = new QCPPainter;
mpainter = nullptr;
visible = true;
// mpainter->setPen(QPen(Qt::green,2));
mParentPlot->addLayer(LayerName());
setLayer(LayerName());
setVisible_(visible);
connect(mParentPlot,&QCustomPlot::mouseMove, this, &Layer::MouseMoveEvent);
connect(mParentPlot,&QCustomPlot::mousePress,this,&Layer::Mousepressevent);
}
设置图层显示
QString Layer::LayerName() const
{
return QStringLiteral("newlayer");
}
void Layer::setVisible_(bool visible)
{
layer = mParentPlot->layer(LayerName());
if(layer)
{
layer->setVisible(visible);
}
}
draw()函数中的绘制
绘制鼠标移动时的跟踪鼠标的十字线:
void Layer::draw(QCPPainter *painter)
{
Q_UNUSED(painter);
mpainter = painter;
mpainter->setPen(QPen(Qt::green,1,Qt::DashDotDotLine));
QPoint p1,p2;
p1.setX(100);
p1.setY(100);
p2.setX(200);
p2.setY(100);
// mpainter->drawLine(p1,p2);
// mpainter->drawEllipse(200,100,100,100);
QCPAxis *axis = mParentPlot->axisRect(0)->axis(QCPAxis::atBottom);
p1.setX(axis->axisRect()->left());
p1.setY(movep.y());
p2.setX(axis->axisRect()->right());
p2.setY(movep.y());
mpainter->drawLine(p1,p2);
p1.setX(movep.x());
p1.setY(0);
p2.setX(movep.x());
p2.setY(axis->axisRect()->bottom());
mpainter->drawLine(p1,p2);
}
以上当时遇到的坑,仅提供给有需求的下伙伴参考,互相交流学习。
demo代码地址:下载