《Qt开发》基于QWT的柱形图绘制

Qwt绘制柱形图

该示例包含以下功能:

1.使用qwt绘制柱形图

2.绘制横向、纵向柱形图

3.柱形图上显示柱子值

《Qt开发》基于QWT的柱形图绘制_第1张图片《Qt开发》基于QWT的柱形图绘制_第2张图片

程序如下:

新建一个Qt Application项目,命名为QwtBarEg,Base class选择Qwidget,

然后添加一个Widget部件,

然后添加一个Qt5Class类,命名为MyBarChart,Base class为QwtPlot,Constructor signature选择Qwidget *parent。

然后定义一个C++头文件defineclass.h

mybarchart头文件内容如下:

#ifndef MYBARCHART_H

#define MYBARCHART_H

#include "QWT\qwt_plot.h"

#include "QWT\qwt_plot_multi_barchart.h"

#include "defineclass.h"

class MyBarChart : public QwtPlot

{

    Q_OBJECT

public:

    MyBarChart(QWidget *parent=NULL);

    ~MyBarChart();

public:

    GJHPlotMultiBarChart *multiBarChart;

    void InitBarChat(int Oritention, QVector< QVector<double> > series, QStringList m_list);

    void setOrientation(int orientation, QStringList m_list);

 };

#endif // MYBARCHART_H

mybarchart源文件内容如下:

#include "mybarchart.h"

#include "QWT\qwt_plot_canvas.h"

#include "QWT\qwt_plot_multi_barchart.h"

#include "QWT\qwt_column_symbol.h"

#include "QWT\qwt_legend.h"

#include "QWT\qwt_scale_draw.h"

#include "QWT\qwt_plot_layout.h"

//自定义一个bar类型继承自QwtPlot

MyBarChart::MyBarChart(QWidget *parent)

    : QwtPlot(parent)

{

    setAutoFillBackground(true);

    setPalette(Qt::white); //设置部件背景色

    canvas()->setPalette(Qt::darkCyan); //设置绘图区域背景色

    setTitle("Bar Chart");

    multiBarChart = new GJHPlotMultiBarChart();

    multiBarChart->setLayoutPolicy(QwtPlotMultiBarChart::AutoAdjustSamples);

    multiBarChart->setSpacing(20);  //每组之间的间隔

    multiBarChart->setMargin(0);

    multiBarChart->attach(this);

    insertLegend(new QwtLegend());

    setAutoReplot(true);

}

MyBarChart::~MyBarChart()

{

}

//参数1相当于二维数组,表示每组每个柱子的值;参数2每组柱子标签

void MyBarChart::InitBarChat(int Oritention, QVector< QVector<double> > series, QStringList m_list)

{

    const int numBars = sizeof(colors) / sizeof(colors[0]);

    //图例名称和大小

    QList<QwtText> titles;  

    for (int i = 0; i < numBars; i++)

    {

        QString title("Bar %1");

        titles += title.arg(i);

    }

    multiBarChart->setBarTitles(titles);

    multiBarChart->setLegendIconSize(QSize(10, 14));

    //图例样式

    for (int i = 0; i < numBars; i++)

    {

        QwtColumnSymbol *symbol = new QwtColumnSymbol(QwtColumnSymbol::Box);

        symbol->setLineWidth(2);

        symbol->setFrameStyle(QwtColumnSymbol::Raised);

        symbol->setPalette(QPalette(colors[i]));

        multiBarChart->setSymbol(i, symbol);

    }

    //设置每组柱子的值

    multiBarChart->m_barValue.clear();

    multiBarChart->m_barValue = series//柱状图上方显示的值

    multiBarChart->setSamples(series);

    setOrientation(Oritention, m_list);

}

void MyBarChart::setOrientation(int orientation, QStringList m_list)

{

    QwtPlot::Axis axis1, axis2;

    if (orientation == 0)

    {

        axis1 = QwtPlot::xBottom;

        axis2 = QwtPlot::yLeft;

        multiBarChart->setOrientation(Qt::Vertical);

    }

    else

    {

        axis1 = QwtPlot::yLeft;

        axis2 = QwtPlot::xBottom;

        multiBarChart->setOrientation(Qt::Horizontal);

    }

    QStringList d_distros = m_list;

    setAxisScale(axis1, 0, multiBarChart->dataSize() - 1, 1.0);

    setAxisAutoScale(axis2);

    setAxisScaleDraw(axis1, new DistroScaleDraw((Qt::Orientation)orientation, d_distros));

    setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignCenter | Qt::AlignBottom);

    //绘制刻度线

    QwtScaleDraw *scaleDraw1 = axisScaleDraw(axis1);

    scaleDraw1->enableComponent(QwtScaleDraw::Backbone, false); //刻度基线

    scaleDraw1->enableComponent(QwtScaleDraw::Ticks, false);    //刻度线

    QwtScaleDraw *scaleDraw2 = axisScaleDraw(axis2);

    scaleDraw2->enableComponent(QwtScaleDraw::Backbone, true);

    scaleDraw2->enableComponent(QwtScaleDraw::Ticks, true);

    //为指定的轴线设置排列画布到轴线比例尺

    plotLayout()->setAlignCanvasToScale(axis1, true);

    plotLayout()->setAlignCanvasToScale(axis2, false);

    plotLayout()->setCanvasMargin(0);

    replot();

}

defindeclass.h头文件内容如下:

#include "QWT\qwt_plot_canvas.h"

#include "QWT\qwt_plot_multi_barchart.h"

#include "QWT\qwt_column_symbol.h"

#include "QWT\qwt_legend.h"

#include "QWT\qwt_scale_draw.h"

#include "QWT\qwt_plot_layout.h"

//设置柱形图的颜色

static const char *colors[] = { "DarkOrchid", "SteelBlue", "Gold" };

//设置柱形图的X轴刻度

class DistroScaleDraw : public QwtScaleDraw

{

public:

    DistroScaleDraw(Qt::Orientation orientation, const QStringList &labels)

        : d_labels(labels)

    {

        //设置间距、中间刻度、主刻度

        setTickLength(QwtScaleDiv::MinorTick, 0);

        setTickLength(QwtScaleDiv::MediumTick, 0);

        setTickLength(QwtScaleDiv::MajorTick, 2);

        //设置旋转角度、对齐方式

        setLabelRotation(0);

        setLabelAlignment(Qt::AlignLeft | Qt::AlignVCenter);

    }

    //The value is converted to a plain text using QLocale::system().toString(value).

    //This method is often overloaded by applications to have individual labels.

    virtual QwtText label(double value) const

    {

        QString text;

        int val = value;

        if (val >= 0 && val < d_labels.size())

        {

            text = d_labels[val];

        }

        return text;  //只能显示英文

    }

    以下方法可以显示中文

    //virtual QwtText label(double value) const

    //{

    //  //QT默认编码为unicode,不能显示中文,使用formLocal8Bit函数可以实现本地字符集GB到unicode的转换

    //  //从而处理中文乱码问题

    //  return QString::fromLocal8Bit("          ");

    //}

    //

    此处是绘制X轴刻度

    //virtual void drawLabel(QPainter *painter, double val) const

    //{

    //  QFont font(QStringLiteral("宋体"), 12, 0);

    //  QRectF rect = this->labelRect(font, val);

    //  QString text("");

    //  int index = qRound(val);

    //  if (index >= 0 && index < d_labels.size())

    //      text = d_labels[index];

    //  QFontMetrics fm(font);

    //  int width = fm.width(text);

    //  //获取左边的坐标

    //  int x = (rect.width() - width) / 2;

    //  QPointF point = this->labelPosition(val);

    //  int left = point.x() - rect.width() / 2 + x;

    //  painter->drawText(QRect(left, point.y(), rect.width()-x , rect.height()), Qt::AlignLeft, text);

    //}

private:

    QStringList d_labels;

};

//绘制柱子及柱形图的柱子的值

class ColumnSymbol : public QwtColumnSymbol

{

public:

    ColumnSymbol(int hit, QColor color) : QwtColumnSymbol()

    {

        d_hit = hit;

        d_color = color;

    }

    //绘制柱形图,代码画矩形,添加标签

    virtual void draw(QPainter *p, const QwtColumnRect &rect) const

    {

        QRectF rect2 = rect.toRect();

        p->setBrush(d_color);

        p->setPen(d_color);

        p->drawRect(rect.toRect());

        QColor tempColor = QColor("black");

        p->setPen(tempColor);

        int top = rect2.top();

        int height = rect2.height();

        Qt::Alignment alignment;

        alignment = Qt::AlignTop | Qt::AlignHCenter;

        p->drawText(QRect(rect2.left() + 1, top, rect2.width() + 2, height), alignment, QString::number(d_hit));

    }

private:

    int d_hit;

    QColor d_color;

};

//每组多个柱形图

class GJHPlotMultiBarChart :public QwtPlotMultiBarChart

{

public:

    GJHPlotMultiBarChart(const QString &title = QString::null) : QwtPlotMultiBarChart()

    {

    }

    QVector< QVector<double> > m_barValue;      //存储多组

    QwtColumnSymbol* specialSymbol(int sampleIndex, int valueIndex) const

    {

        ColumnSymbol *pSymbol = new ColumnSymbol(m_barValue[sampleIndex][valueIndex], colors[valueIndex]);

        return pSymbol;

    }

};

然后利用上面的类绘制柱形图

在qwtbareg.h中添加#include "mybarchart.h"头文件,然后添加类对象和函数

MyBarChart *myBarChart;

void Init(QString xlabel, QString ylabel);

void PrepareData();

在qwtbareg.cpp中添加上述函数的定义

void QwtBarEg::Init(QString xlabel, QString ylabel)

{

    //初始化类对象

    myBarChart = new MyBarChart();

    //添加坐标轴的标题

    myBarChart->setAxisTitle(QwtPlot::xBottom, xlabel);

    myBarChart->setAxisTitle(QwtPlot::yLeft, ylabel);

   

    //设置布局

    QHBoxLayout *layout = new QHBoxLayout();

    layout->setMargin(0);

    layout->setContentsMargins(QMargins(0, 0, 0, 0));

    layout->addWidget(myBarChart);

    ui.widget->setLayout(layout);

}

//产生数据

void QwtBarEg::PrepareData()

{

    QVector< QVector<double> > values;

    QStringList strList;

    int oritention = 1; //1:绘制横向柱形图;0:绘制纵向柱形图

    qsrand(QTime::currentTime().second()); //随机数种子

    for (int i = 0; i < 5; i++) 

    {

        QVector<double> val;

        for (int j = 0; j < 3; j++)

        {

            double randomData = 20 + (qrand() % 30);  //随机数

            val += randomData;

        }

        values += val;  //添加每组的多个值

        strList += QString("Group %1").arg(i);     //每组柱形图的标签

    }

    myBarChart->InitBarChat(oritention, values, strList);

}

你可能感兴趣的:(Qt,qt,开发语言)