2011-02-24 167 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; 
}