C++ 在Qt 4中直接在鼠标下方缩放图像
与google.com/maps类似,我希望这样,如果我的鼠标在QGraphicsSitem上,那么当我前后移动滚轮鼠标时,鼠标下的图像区域就是QGraphicsView的中心区域 我可以在我创建的自定义QGraphicsSite的wheelEvent方法中实现这一点吗 我有一些这样的代码C++ 在Qt 4中直接在鼠标下方缩放图像,c++,qt4,image-scaling,C++,Qt4,Image Scaling,与google.com/maps类似,我希望这样,如果我的鼠标在QGraphicsSitem上,那么当我前后移动滚轮鼠标时,鼠标下的图像区域就是QGraphicsView的中心区域 我可以在我创建的自定义QGraphicsSite的wheelEvent方法中实现这一点吗 我有一些这样的代码 update(); qreal factor = 1.2; if (event->delta() < 0) factor = 1.0 / factor; scale(factor, facto
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());
update();
qreal系数=1.2;
如果(事件->增量()<0)
系数=1.0/系数;
尺度(因子,因子);
scaleFactor*=因子;
this->scene()->setscen直立(0,0,this->boundingRect().width(),this->boundingRect().height());
我可以添加什么来达到预期效果
例如,在谷歌地图中,如果你将鼠标放在犹他州上方,并继续用滚轮鼠标放大,最终犹他州是视口中唯一剩下的东西。让我们以更直接的方式重新表述你的目标。车轮事件:
horizontalScrollbar().setValue(x);
verticalScrollbar().setValue(y);
这将滚动场景,使(x,y)位于视图的左上角。但是您希望(x,y)位于鼠标位置(相对于QGraphicsView)。因此,您需要滚动到(x-mx,y-my),其中(mx,my)是相对于QGraphicsView的鼠标位置,(x,y)是滚轮事件之前鼠标下方的场景位置
这是未经测试的,在细节上可能是错误的(例如在QScrollBar::setValue的确切行为中),但数学概念是正确的,因此它应该足以让它工作。另请参见
setTransformationAnchor(QGraphicsView::AnchorUnderMouse)代码>
这个方程就像
边距=-half_overflow+((中心偏移-单击偏移)*
调整_比率)-(中心_偏移-单击_偏移))
。。。你必须为x和y做这件事
下面我将粘贴一些代码来实现这一点,但请记住,这段代码处理的是方形图像,所以我使用宽度表示宽度和高度。
要在矩形图像上使用它,您还需要获取高度,并在所有Y计算中使用它,其中我有宽度,以及设置我使用的所有变量,如内容宽度等。但是算法都在那里,您可以从代码中计算出来
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>
我可以在QGraphicsItem的控制盘事件中执行此操作吗?该项目是什么有wheelEvent在它,而不是QGraphicsViewAh,我想你的wheelEvent是在QGV。如果是在QGI中,您应该仍然能够做到这一点。唯一的区别在于确定(x,y)
(使用qgraphicsceneouseevent::screenPos)和(mx,my)
(使用qgraphicsceneouseevent::scenePos)的方式。无论如何,我认为在QGV中实现wheelEvent比在QGI中实现wheelEvent更干净。
#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;
}