2011-02-24 161 views
0

到google.com/maps类似,我想它,如果我的鼠标在的QGraphicsItem,然后当我移动滚轮鼠标向前和向后,图像的区域下的鼠标是在我的QGraphicsView中居中。缩放图像4

我可以在自定义的wheelEvent方法做到这一点QGraphicsIte我已经创建了?

我有这样

update(); 
qreal factor = 1.2; 
if (event->delta() < 0) 
    factor = 1.0/factor; 
scale(factor, factor); 
scaleFactor *=factor; 
this->scene()->setSceneRect(0,0,this->boundingRect().width(), this->boundingRect().height()); 

我能加入到这样的代码,得到期望的效果?

举个例子,在谷歌地图,如果你将鼠标放在犹他,并保持与滚轮鼠标放大,最终犹他是留在视口中的唯一的事情。

回答

0

让我们改一下你的目标更直接的方式。在滚轮事件:

  1. 场景应该放大/缩小
  2. 鼠标下的场景位置应保持鼠标

你已经实现了(1)随着规模号召下。剩下的是(2)。滚动视图到一定位置时,你需要做的:

horizontalScrollbar().setValue(x); 
verticalScrollbar().setValue(y); 

这滚动的一幕让(X,Y)是在视图的左上角。但是你想(x,y)在鼠标位置(相对于QGraphicsView)。因此,您需要滚动到(x-mx,y-my)其中(mx,my)是鼠标相对于QGraphicsView的位置,(x,y)是轮子事件之前鼠标下的场景位置。

这是未经测试的,可能是错误的细节(例如QScrollBar :: setValue的确切行为),但数学概念是正确的,所以它应该足以让你得到它的工作。

+0

我能做到这一点从的​​QGraphicsItem的轮事件中?该项目是什么有wheelEvent,而不是QGraphicsView – Derek 2011-02-24 20:20:10

+0

啊,我认为你的wheelEvent是在QGV。如果它在QGI中,你应该仍然可以做到。唯一的区别在于你确定'(x,y)'(使用QGraphicsSceneMouseEvent :: screenPos)和'(mx,my)'(使用QGraphicsSceneMouseEvent :: scenePos)的方式。无论如何,我认为在QGV而不是QGI中实施wheelEvent更清洁。 – 2011-02-24 21:49:32

0

钍方程是像,,,

余量= -half_overflow +(((CENTER_OFFSET - click_offset)* resize_ratio) - (center_offset - click_offset));

...你必须这样做x和y。

下面一些代码,做它,但请记住,与方形的图像,此代码的交易,所以我用宽度宽度和高度生病粘贴。 为了在矩形图像上使用它,您还需要获取高度,并在所有Y宽度的计算中使用该高度,以及设置所有像使用content_width等的变量。但算法都在那里你可以解决它从代码...

 zoomChart: function(e) 
     { 
       var chart_max = 2048; 
       var zoom_max = egapp.user.options.zoom_multiplier || 2; // >= 2 
       var chart_bounds = $('#egapp_chart_bounds'); 
       var chart_imgs = chart_bounds.find('img'); 
       var width = chart_imgs.width(); 
       if (width == chart_bounds.width()) { // zoom in 
         // margin = -half_overflow + (((center_offset - click_offset) * resize_ratio) - (center_offset - click_offset)); 
         chart_bounds.removeClass('egapp_zoom_in'); 
         if (width == chart_max) 
           return; 
         chart_bounds.addClass('egapp_zoom_out'); 
         var new_width = parseInt(width * zoom_max); 
         if (new_width > chart_max) 
           new_width = chart_max; 
         var ratio = new_width/width; 
         var moveX = moveY = -((new_width - width)/2); 
         var chart_offset = chart_bounds.offset(); 
         var offsetX = (chart_offset.left + (width/2)) - e.pageX; 
         var offsetY = (chart_offset.top + (width/2)) - e.pageY; 
         moveX += parseInt((offsetX * ratio) - offsetX); 
         moveY += parseInt((offsetY * ratio) - offsetY); 
         chart_imgs.animate({width: new_width+'px', height: new_width+'px', marginLeft: moveX+'px', marginTop: moveY+'px'}, 'fast'); 
         chart_bounds.addClass('egapp_zoom_out'); 
       } 
       else { // zoom out 
         var new_width = egapp.content_width - 10; 
         chart_imgs.animate({width: new_width+'px', height: new_width+'px', marginLeft: 0, marginTop: 0}, 'fast'); 
         chart_bounds.removeClass('egapp_zoom_out').addClass('egapp_zoom_in'); 
       } 
     }, 

的HTML是一样的东西...

<div id="egapp_chart_bounds" style="width: 608px; height: 608px;" class="egapp_zoom_in"> 
    <img id="egapp_timeline_chart" src="some.image" class="egapp_chart" style="width: 608px; height: 608px; margin-left: 0px; margin-top: 0px;"> 
    <img id="egapp_expression_chart_9" src="overlay.image" class="egapp_chart_overlay" style="width: 608px; height: 608px;"> 
</div> 

而CSS是像...

#egapp_chart_bounds{ 
     overflow: hidden; 
} 
.egapp_chart, .egapp_chart_overlay{ 
     position: absolute; 
} 

.egapp_zoom_in{ 
     cursor: -moz-zoom-in; 
     cursor: -webkit-zoom-in; 
     cursor: zoom-in; 
} 
.egapp_zoom_out{ 
     cursor: -moz-zoom-out; 
     cursor: -webkit-zoom-out; 
     cursor: zoom-out; 
}