QWT自定义坐标轴标签及同一条曲线显示多种形状样本点

一:先上效果图,横轴纵轴可以根据需求显示任意文本,每个样本点也可以显示成任意形状

QWT自定义坐标轴标签及同一条曲线显示多种形状样本点_第1张图片

 

二:横纵轴显示任意文本实现:

 QwtPlot类提供如下函数,用于设置坐标轴文本显示。

void setAxisScaleDraw( int axisId, QwtScaleDraw * );

所以通过继承QwtScaleDraw类,重写下面的虚函数,按照自定义的规则返回文本。

virtual QwtText label(double v) const;

具体实现,将坐标轴的文本放到list里,挨个取值:

#pragma once
#include "qwt_scale_draw.h"

class CustomScakeDraw : public QwtScaleDraw
{
public:
    //scale:文本标签数组  labelRotation:斜率
    CustomScakeDraw(const QList& scale, double labelRotation = 0) : m_scale(scale)
    {
        setLabelRotation(labelRotation);
    }

    virtual QwtText label(double v) const
    {
        QString text;
        int value = v;
        if (value >= 0 && value < m_scale.size())
        {
            text = m_scale[value];
        }
        return text;
    }

private:
    QList m_scale;
};

使用示例:

    //设置Y轴坐标
    QList valueY{"A", "B", "C", "D", "E", "F", "G"};
    ui->plot->setAxisScale(QwtPlot::yLeft, 0, valueY.size() - 1, 1); //从0开始,步长为1,若从负数开始,则要加个偏移量,可在CustomScakeDraw类中加
    ui->plot->setAxisMaxMinor(QwtPlot::yLeft, 0); //取消小格
    ui->plot->setAxisScaleDraw(QwtPlot::yLeft, new CustomScakeDraw(valueY));

三:同一条曲线显示多种形状样本点 

QwtPlotCurve类提供了设置样本点形状的函数:void setSymbol( QwtSymbol* );,但是只支持同一条曲线所有样本点的形状都一致。若要在同一条曲线上根据样本点的值显示不同的形状,就需要继承QwtPlotCurve类。

实现:

1)增加接口:setSymbols 

//CustomPlotCurve 继承于 QwtPlotCurve
void CustomPlotCurve::setSymbols(QVector symbols)
{
    for (int i = 0; i < d_data->symbols.size(); i++)
    {
        QwtSymbol* temp = d_data->symbols[i];
        delete temp;
        d_data->symbols[i] = NULL;
    }

    d_data->symbols = symbols;
    qwtUpdateLegendIconSize(this);
    legendChanged();
    itemChanged();
}

2)重载drawSeries

void CustomPlotCurve::drawSeries( QPainter* painter,
                                 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
                                 const QRectF& canvasRect, int from, int to ) const
{
    const size_t numSamples = dataSize();
    if ( !painter || numSamples <= 0 )
    {
        return;
    }

    if ( to < 0 )
    {
        to = numSamples - 1;
    }

    if ( qwtVerifyRange( numSamples, from, to ) > 0 )
    {
        painter->save();
        painter->setPen( d_data->pen );
        drawCurve( painter, d_data->style, xMap, yMap, canvasRect, from, to );
        painter->restore();

        if(d_data->symbols.size() > 0)
        {
            for (int i = from; i <= to; i++)
            {
                if (i >= d_data->symbols.size())
                {
                    break;
                }

                if (d_data->symbols[i]->style() != QwtSymbol::NoSymbol)
                {
                    painter->save();
                    drawSymbols(painter, *d_data->symbols[i], xMap, yMap, canvasRect, i, i);
                    painter->restore();
                }
            }
        }
        else
        {
            if (d_data->symbol && ( d_data->symbol->style() != QwtSymbol::NoSymbol ))
            {
                painter->save();
                drawSymbols( painter, *d_data->symbol, xMap, yMap, canvasRect, i, to );
                painter->restore();
            }
        }
    }
}

3)样本点画任意图形

QwtSymbol类提供了一些常用的图形,若不能满足需求,则需要自定义。

可用圈中的构造函数,先使用QPainterPath画好图,传给构造函数QWT自定义坐标轴标签及同一条曲线显示多种形状样本点_第2张图片

 4)使用示例

QVector& symbols;
for(int i = 0; i < 10; i++)
{
	if(i % 2 == 0)
	{
		symbols << new QwtSymbol(QwtSymbol::Ellipse, QBrush(color), QPen(color, 1), QSize(diameter, diameter));
	}
	else
	{
        QPainterPath path;
        //使用path画任意图形
            .
            .
            .
		symbols << new QwtSymbol(path, QBrush(Qt::white), QPen(Qt::blue, 1));
	}
}


CustomPlotCurve* curve = new CustomPlotCurve;
//各种设置
            .
            .
            .
curve->setSymbols(symbols); //添加样本点形状

你可能感兴趣的:(QT实战经验之谈,qt,c++)