您的位置:首页 > 编程语言 > PHP开发

Qwt源码解读之QwtPlot类

2014-07-04 15:38 393 查看
QwtPlot类是一个二维绘图部件,继承自QFrame 和 QwtPlotDict。不过严格的说来,它只是一个视图窗口,真正的绘制设备是它的中心部件QwtPlotCanvas类。在QwtPlot的画布上可以显示不限数量的图元项(plot items)。这些图元项可以是曲线(QwtPlotCurve),标签(QwtPlotMarker),网格(QwtPlotGrid),或者其它任意的从QwtPlotItem派生出来的子类。
一个QwtPlot有四条坐标抽,每一个项都依附于X轴或者Y轴。每一个轴的刻度可以通过set (QwtScaleDiv)或者根据绘制的图元通过算法(QwtScaleEngine)单独配置。

QwtPlotDict类是一个Item的字典,用于管理添加到QwtPlot上的所有图元项。QwtPlotDict 按照Z值的递增顺序组织items. 如果autoDelete()设置为可用,所有依附的items会在QwtPlotDict的析构函数中被删除。

QwtPlotCanvas类:QwtPlot的画布,继承自QFrame。

在QwtPlot上所有图元(QwtPlotItem)的绘制都是源于QwtPlotCanvas类的paintEvent(). paintEvent()调用QwtPlotCanvas::drawCanvas(), QwtPlotCanvas::drawCanvas() 调用 QwtPlot::drawCanvas( QPainter *painter ), QwtPlot::drawCanvas( QPainter *painter )会调用QwtPlot::drawItems(), QwtPlot::drawItems()会调用所有图元的纯虚函数QwtPlotItem::draw()
= 0; 绘制图元自己。

因此,从上面的绘制流程来看,QwtPlot只是一个呈现图元的视口,相当于View; 而QwtPlotCanvas 才是真正的画布(即绘制设备),它是QwtPlot的一个成员,或者说中心部件,用于展现所有的图元,相当于QGraphicsView::setViewport( QWidget * widget ); 【从QAbstractScrollArea继承而来】中的widget;QwtPlotDict是一个非常重要的类,它被QwtPlot继承,用于协助QwtPlot管理所有的图元项,感觉相当于Scene;
QwtPlotItem 即为图元,相当于Item。
如何添加一个图元?

Qwt中添加一个图元的方式不同于Qt的GraphicsView框架。QwtPlot本身并不具备添加图元的操作,一个图元自己有权力决定被添加到哪个QwtPlot,图元通过以下两个接口实现这项功能。

void attach( QwtPlot *plot );

void detach();

看看这两个接口的具体实现:

/*!
\brief Attach the item to a plot.

This method will attach a QwtPlotItem to the QwtPlot argument. It will first
detach the QwtPlotItem from any plot from a previous call to attach (if
necessary). If a NULL argument is passed, it will detach from any QwtPlot it
was attached to.

\param plot Plot widget
\sa detach()
*/
void QwtPlotItem::attach( QwtPlot *plot )
{
if ( plot == d_data->plot )
return;

// remove the item from the previous plot

if ( d_data->plot )
{
if ( d_data->plot->legend() )
d_data->plot->legend()->remove( this );

d_data->plot->attachItem( this, false );

if ( d_data->plot->autoReplot() )
d_data->plot->update();
}

d_data->plot = plot;

if ( d_data->plot )
{
// insert the item into the current plot

d_data->plot->attachItem( this, true );
itemChanged(); // 这个函数里面实现了QwtPlot的更新和图元对应示例图QwtLegendItem的更新
}
}

/*!
\brief This method detaches a QwtPlotItem from any
QwtPlot it has been associated with.

detach() is equivalent to calling attach( NULL )
\sa attach()
*/
void QwtPlotItem::detach()
{
attach( NULL );
}


再看看itemChanged()的实现代码,有助于我们理解QwtPlotItem 和 QwtLegend 是如何实现绑定的。

/*!
Update the legend and call QwtPlot::autoRefresh for the
parent plot.

\sa updateLegend()
*/
void QwtPlotItem::itemChanged()
{
if ( d_data->plot )
{
if ( d_data->plot->legend() )
updateLegend( d_data->plot->legend() );

d_data->plot->autoRefresh();
}
}


上面的updateLegend()是在QwtLegendItemManager中定义的纯虚函数:

virtual void QwtLegendItemManager::updateLegend( QwtLegend *legend ) const = 0;


在QwtPlotItem及其派生类中会根据需要重新实现updateLegend( QwtLegend *legend )函数,实现代码中会为QwtPlotItem在QwtLegend中创建(通过legendItem())对应的示例图示。

而legendItem()是在QwtLegendItemManager中定义的纯虚函数:
virtual QWidget *legendItem() const = 0;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: