Qwt样例之tvplot
Qwt的tvplot这个样例主要讲的是如何画柱状图(Histogram)

整个过程从继承自QwtPlot的TVPlot开始,建立画布、座标轴、图例,然后在图上画网格线和柱状图
最后进行图像的初始化,确保右边图例的点按状态和图像显示一致
其实也比较简单,用别人的库最重要的是熟悉每个类和成员函数…
main.cpp和tvplot.h可以忽略不计,重点在tvplot.cpp:
#include <stdlib.h>
#include <qpen.h>
#include <qwt_plot_layout.h>
#include <qwt_legend.h>
#include <qwt_legend_item.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_histogram.h>
#include <qwt_column_symbol.h>
#include <qwt_series_data.h>
#include "tvplot.h"
class Histogram: public QwtPlotHistogram
{
public:
Histogram(const QString &, const QColor &);
void setColor(const QColor &);
void setValues(uint numValues, const double *);
};
Histogram::Histogram(const QString &title, const QColor &symbolColor):
QwtPlotHistogram(title)
{
setStyle(QwtPlotHistogram::Columns);
setColor(symbolColor);
}
void Histogram::setColor(const QColor &symbolColor)
{
QColor color = symbolColor;
color.setAlpha(180); // 真烧包,还半透明
setPen(QPen(Qt::black));
setBrush(QBrush(color));
QwtColumnSymbol *symbol = new QwtColumnSymbol(QwtColumnSymbol::Box);
symbol->setFrameStyle(QwtColumnSymbol::Raised);
symbol->setLineWidth(2);
symbol->setPalette(QPalette(color));
setSymbol(symbol);
}
void Histogram::setValues(uint numValues, const double *values)
{
// QwtIntervalSeriesData = QwtIntervalSample * n
// QwtIntervalSample = value + interval
// interval = minValue + maxValue
// value,minValue,maxValue : double
QVector<QwtIntervalSample> samples(numValues);
for ( uint i = 0; i < numValues; i++ )
{
QwtInterval interval(double(i), i + 1.0);
interval.setBorderFlags(QwtInterval::ExcludeMaximum);
samples[i] = QwtIntervalSample(values[i], interval);
}
setData(new QwtIntervalSeriesData(samples));
}
TVPlot::TVPlot(QWidget *parent):
QwtPlot(parent)
{
setTitle("Watching TV during a weekend");
setCanvasBackground(QColor(Qt::gray));
plotLayout()->setAlignCanvasToScales(true);
setAxisTitle(QwtPlot::yLeft, "Number of People");
setAxisTitle(QwtPlot::xBottom, "Number of Hours");
QwtLegend *legend = new QwtLegend;
legend->setItemMode(QwtLegend::CheckableItem);
insertLegend(legend, QwtPlot::RightLegend);
populate();
// 点选图例时,显示相应的图像
connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)),
SLOT(showItem(QwtPlotItem *, bool)));
replot(); // creating the legend items
// itemList()返回当前attach到plot上的item,参数是类型
QwtPlotItemList items = itemList(QwtPlotItem::Rtti_PlotHistogram);
for ( int i = 0; i < items.size(); i++ )
{
// items.size()是2,即一个夏天一个冬天
if ( i == 0 )
{
// 根据item[i]查出相应的图例
QwtLegendItem *legendItem =
(QwtLegendItem *)legend->find(items[i]);
if ( legendItem )
legendItem->setChecked(true);
items[i]->setVisible(true);
}
else
items[i]->setVisible(false);
}
setAutoReplot(true);
}
void TVPlot::populate()
{
QwtPlotGrid *grid = new QwtPlotGrid;
grid->enableX(false); // 网格线整体开关
grid->enableY(true);
grid->enableXMin(false);
grid->enableYMin(false); // 最小刻度网格线
// 网格线有两种,major和minor(最小刻度)
// 下面是设置mojor线的样式
grid->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
grid->attach(this);
const double juneValues[] = { 7, 19, 24, 32, 10, 5, 9, 9 };
const double novemberValues[] = { 4, 15, 22, 34, 13, 8, 4, 5 };
Histogram *histogramJune = new Histogram("Summer", Qt::red);
histogramJune->setValues(
sizeof(juneValues) / sizeof(double), juneValues);
histogramJune->attach(this);
Histogram *histogramNovember = new Histogram("Winter", Qt::blue);
histogramNovember->setValues(
sizeof(novemberValues) / sizeof(double), novemberValues);
histogramNovember->attach(this);
}
void TVPlot::showItem(QwtPlotItem *item, bool on)
{
item->setVisible(on);
}