Qwt源码解读之QwtPlot类

       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的画布【Canvas of a 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;




  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值