2018年 QCustomPlot绘图的相关整理,后附demo源码。

 

https://download.csdn.net/download/qq_20088499/10720690

俗话说的好,不上图说个JB。来!动图。

QCustomPlot的普通画线,我将折线花在了QLabel里面,

你也可以重载其他控件,或者直接画在主界面上。

下面是在另一个图层layer上的绘图。

为啥要用QCustomPlot

最近在写一个辅助性的平台软件,基本功能是将矢量数据更直观的表现出来,就是画线呗,折线。领导让最大化的尽可能的完善一下,超越他之前的版本,看多代码之后觉得使用的框架不是很方便,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代码地址:下载

你可能感兴趣的:(知识点,qt,可能会遇到的问题,Qt图像处理,Qt,QCustomPlot)