QGraphicsView 指定数据区域显示,锚点缩放

--------------  aa.h --------------  

#ifndef AA_H
#define AA_H

#include <QtGui/QMainWindow>

#include <QGraphicsScene>
 
class MyGraphicsView : public QGraphicsView
{
    Q_OBJECT

public:
     MyGraphicsView(QWidget *parent = 0):QGraphicsView(parent){ m_b_wheel_at_anchor = true ; }

     bool   m_b_wheel_at_anchor ;

     void    zoom_full() { _do_zoom( scene()->sceneRect()) ; 
                             /* or next code
                             QRect abc = viewport()->geometry(); 
                             double dx = abc.width()/ scene()->width();
                             double dy = abc.height()/ scene()->height();  
                             setTransform( QTransform());
                             scale( min(dx,dy), min(dx,dy) ); 
                             centerOn(  scene()->sceneRect().center()); */ 
     }
     void    _do_zoom( double scale_factor, const QPoint & anchor );
     void    _do_zoom(const QRectF & data_extent  ); // 把数据区域尽量显示在窗口
     double  calc_full_scale();

private: 
    virtual void   wheelEvent(QWheelEvent *event); 
    virtual void   resizeEvent(QResizeEvent *event);

};

#include "ui_aa.h"

class aa : public QMainWindow
{
    Q_OBJECT

扫描二维码关注公众号,回复: 6085183 查看本文章

public:
    aa(QWidget *parent = 0, Qt::WFlags flags = 0);
 
    void  load_data() ;

private:
    Ui::aaClass ui;

    MyGraphicsView  * m_view ;
    QGraphicsScene *  m_scence ;

public slots:
    void on_actionZoomin_triggered();
    void on_actionZoomout_triggered(); 
    void on_actionZoomfull_triggered();
    void on_actionLoad_triggered();
    void on_actionWheel_no_scroll_triggered();
};

#endif // AA_H
 

----------  aa.cpp -----

#include "stdafx.h"

#include <assert.h>

#include "aa.h"

inline void operator *= ( QRectF & b, double scale )
{
    QPointF center  = b.center() ;  
    b.setWidth( b.width() * scale ) ;
    b.setHeight( b.height() * scale );
    b.moveCenter( center ) ;
}

aa::aa(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags)
{
    ui.setupUi(this);
    m_scence = new QGraphicsScene( this);
     
    m_view =  ui.centralWidget  ;
    m_view->setScene( m_scence );

    ui.actionWheel_no_scroll->setCheckable( true );
    ui.actionWheel_no_scroll->setChecked( m_view->m_b_wheel_at_anchor   );
}

void aa::on_actionLoad_triggered()
{
    m_scence->addItem( new QGraphicsRectItem( -60.,-60.,100.,100.0)) ;
    m_scence->addItem( new QGraphicsRectItem( 20.,20.,10.,10.0)) ;
    m_scence->addItem( new QGraphicsRectItem( 100., 0.,30.,40.0)) ;
    m_scence->addItem( new QGraphicsRectItem( 0., 80.,30.,50.0)) ;
    //....
    QRectF bound ;
    foreach( auto it, m_scence->items()){
        bound |= it->boundingRect() | it->childrenBoundingRect();
    }

    bound *= 1.1 ;
    
    m_scence->setSceneRect( bound ) ;

    m_view->zoom_full();
     

void aa::on_actionWheel_no_scroll_triggered()

    m_view->m_b_wheel_at_anchor = !m_view->m_b_wheel_at_anchor ; 
    
    ui.actionWheel_no_scroll->setChecked( m_view->m_b_wheel_at_anchor );
}

void  aa::on_actionZoomfull_triggered()

    m_view->zoom_full(); 
}

void  aa::on_actionZoomin_triggered()
{
    const QRect & abc = m_view->viewport()->geometry(); 
    m_view->_do_zoom( 1.25, abc.center() );    // 等效于     m_view->setTransformationAnchor(QGraphicsView::AnchorViewCenter);  m_view->scale(1.25,1.25);

}


void  aa::on_actionZoomout_triggered()
{
    const QRect & abc = m_view->viewport()->geometry(); 
    m_view->_do_zoom( 0.75, abc.center() );
}

//////////// MyGraphicView ////  

// calc scale when show full_data_externt
double MyGraphicsView::calc_full_scale() 
{  
    double dx = viewport()->geometry().width()/scene()->width();
    double dy = viewport()->geometry().height()/scene()->height(); 
    // return min( dx, dy) ;
    return dx < dy ? dx : dy ; 
}

void MyGraphicsView::resizeEvent(QResizeEvent *event)
{
    // qt no resizing-event 
    if( event->oldSize().isEmpty() || event->size().isEmpty()){
        QGraphicsView::resizeEvent( event ) ;
        return ; 
    } 
 
    QPolygonF data = mapToScene( QRect( QPoint(0,0),event->oldSize() ) ) ; 
      _do_zoom( data.boundingRect()) ; 

void    MyGraphicsView::wheelEvent(QWheelEvent *event)

    if( m_b_wheel_at_anchor || QApplication::keyboardModifiers() == Qt::ControlModifier  ){  
        qreal factor = 1 + event->delta() / 1200.00; 
        _do_zoom( factor , event->pos()) ;   
        //     等效于   setTransformationAnchor(QGraphicsView::AnchorUnderMouse);  m_view->scale(factor,factor);
    }
    else{
        QGraphicsView::wheelEvent(event) ;
    } 
}

void MyGraphicsView::_do_zoom(  const QRectF & data_extent )
{
    QRect  abc =  viewport()->geometry();
    double scale_x = abc.width() /data_extent.width() ;
    double scale_y = abc.height() / data_extent.height();
    if( scale_x > scale_y ) scale_x = scale_y;
     
    QMatrix matrix( scale_x, 0, 0, scale_x, data_extent.center().x(), data_extent.center().y() ) ;  //此处直接改变了 坐标系统的 偏移, 即直接偏移映射, 无需改变widget的逻辑窗口位置(centerOn)  //
    setMatrix( matrix) ; 
     
}


void MyGraphicsView::_do_zoom( double scale_factor, const QPoint & anchor )
{
    assert( scale_factor > 0 );


    double scale = transform().m11(); //( assert( f.m11() = f.m22());  
    
    double full_scale = calc_full_scale(); 
    double dest_scale = scale * scale_factor ;
     
    // 根据需要,限制缩放极限值
//    if( scale_factor > 1.0 && ( dest_scale > 2.0 ||  dest_scale > full_scale * 10.0 ) ) return ; 
//    if( scale_factor < 1.0 && dest_scale < full_scale * .075  ) return ;

    // device_point--2--logic_point--2--data_point 
    QPointF data_anchor = mapToScene( anchor) ;
 
    QGraphicsView::scale(  scale_factor, scale_factor );
  
    // distance = (device_point -- widget_center)
    QPoint widget_center =  viewport()->geometry().center(); 
    QPoint dis =  widget_center - anchor ;

    QPointF new_data_center = QPointF( data_anchor.x() + dis.x() / dest_scale ,  data_anchor.y() + dis.y() / dest_scale );
     centerOn( new_data_center);
    
}
 

------------------- aa.ui ------------

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>aaClass</class>
 <widget class="QMainWindow" name="aaClass">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>695</width>
    <height>507</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>aa</string>
  </property>
  <widget class="MyGraphicsView" name="centralWidget"/>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>695</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
   <addaction name="actionLoad"/>
   <addaction name="actionZoomin"/>
   <addaction name="actionZoomout"/>
   <addaction name="actionZoomfull"/>
   <addaction name="actionWheel_no_scroll"/>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <action name="actionZoomin">
   <property name="text">
    <string>zonnin</string>
   </property>
  </action>
  <action name="actionZoomout">
   <property name="text">
    <string>zoomout</string>
   </property>
  </action>
  <action name="actionLoad">
   <property name="text">
    <string>load</string>
   </property>
  </action>
  <action name="actionZoomfull">
   <property name="text">
    <string>zoomfull</string>
   </property>
   <property name="toolTip">
    <string>zoomfull</string>
   </property>
  </action>
  <action name="actionWheel_no_scroll">
   <property name="text">
    <string>wheel_no_scroll</string>
   </property>
   <property name="toolTip">
    <string>zoom at mouse_anchor</string>
   </property>
  </action>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <customwidgets>
  <customwidget>
   <class>MyGraphicsView</class>
   <extends>QWidget</extends>
   <header>aa.h</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources>
  <include location="aa.qrc"/>
 </resources>
 <connections/>
</ui>
 

猜你喜欢

转载自blog.csdn.net/hanxb/article/details/88574458