-------------- 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
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>