qt鼠标悬停图片放大,QGraphicsView使用鼠标滚轮在鼠标位置放大和缩小

I have an application with a QGraphicsView window in the middle of the screen. I want to be able to zoom in and out using a mouse wheel scroll.

Currently I have re-implemented QGraphicsView and overriden the mouse scroll function so that it doesn't scroll the image (like it does by default).

void MyQGraphicsView::wheelEvent(QWheelEvent *event)

{

if(event->delta() > 0)

{

emit mouseWheelZoom(true);

}

else

{

emit mouseWheelZoom(false);

}

}

so when I scroll, I'm emitting a signal true if mouse wheel forward false if mouse wheel back.

I have then connected this signal to a slot (zoom function see below) in the class that handles my GUI stuff. Now basically I think my zoom function just isn't the best way to do it at all I have seen some examples of people using the overriden wheelevent function to set scales but I couldn't really find a complete answer.

So instead I have done this but it's not perfect by any means so I'm looking for this to be tweaked a bit or for a working example using scale in the wheel event function.

I initialize m_zoom_level to 0 in the constructor.

void Display::zoomfunction(bool zoom)

{

QMatrix matrix;

if(zoom && m_zoom_level < 500)

{

m_zoom_level = m_zoom_level + 10;

ui->graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);

matrix.scale(m_zoom_level, m_zoom_level);

ui->graphicsView->setMatrix(matrix);

ui->graphicsView->scale(1,-1);

}

else if(!zoom)

{

m_zoom_level = m_zoom_level - 10;

ui->graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);

matrix.scale(m_zoom_level, m_zoom_level);

ui->graphicsView->setMatrix(matrix);

ui->graphicsView->scale(1,-1);

}

}

As you can see above I'm using a QMatrix and scaling that and setting it to the Graphicsview and setting the transformation anchor to under mouse, but its just not working perfectly sometimes if I'm scrolling loads it will just start to zoom in only (which I think is to do with the int looping over or something).

As I said help with this or a good example of scale under mouse would be great.

解决方案

Such zooming is a bit tricky. Let me share my own class for doing that.

Header:

#include

#include

/*!

* This class adds ability to zoom QGraphicsView using mouse wheel. The point under cursor

* remains motionless while it's possible.

*

* Note that it becomes not possible when the scene's

* size is not large enough comparing to the viewport size. QGraphicsView centers the picture

* when it's smaller than the view. And QGraphicsView's scrolls boundaries don't allow to

* put any picture point at any viewport position.

*

* When the user starts scrolling, this class remembers original scene position and

* keeps it until scrolling is completed. It's better than getting original scene position at

* each scrolling step because that approach leads to position errors due to before-mentioned

* positioning restrictions.

*

* When zommed using scroll, this class emits zoomed() signal.

*

* Usage:

*

* new Graphics_view_zoom(view);

*

* The object will be deleted automatically when the view is deleted.

*

* You can set keyboard modifiers used for zooming using set_modified(). Zooming will be

* performed only on exact match of modifiers combination. The default modifier is Ctrl.

*

* You can change zoom velocity by calling set_zoom_factor_base().

* Zoom coefficient is calculated as zoom_factor_base^angle_delta

* (see QWheelEvent::angleDelta).

* The default zoom factor base is 1.0015.

*/

class Graphics_view_zoom : public QObject {

Q_OBJECT

public:

Graphics_view_zoom(QGraphicsView* view);

void gentle_zoom(double factor);

void set_modifiers(Qt::KeyboardModifiers modifiers);

void set_zoom_factor_base(double value);

private:

QGraphicsView* _view;

Qt::KeyboardModifiers _modifiers;

double _zoom_factor_base;

QPointF target_scene_pos, target_viewport_pos;

bool eventFilter(QObject* object, QEvent* event);

signals:

void zoomed();

};

Source:

#include "Graphics_view_zoom.h"

#include

#include

#include

#include

Graphics_view_zoom::Graphics_view_zoom(QGraphicsView* view)

: QObject(view), _view(view)

{

_view->viewport()->installEventFilter(this);

_view->setMouseTracking(true);

_modifiers = Qt::ControlModifier;

_zoom_factor_base = 1.0015;

}

void Graphics_view_zoom::gentle_zoom(double factor) {

_view->scale(factor, factor);

_view->centerOn(target_scene_pos);

QPointF delta_viewport_pos = target_viewport_pos - QPointF(_view->viewport()->width() / 2.0,

_view->viewport()->height() / 2.0);

QPointF viewport_center = _view->mapFromScene(target_scene_pos) - delta_viewport_pos;

_view->centerOn(_view->mapToScene(viewport_center.toPoint()));

emit zoomed();

}

void Graphics_view_zoom::set_modifiers(Qt::KeyboardModifiers modifiers) {

_modifiers = modifiers;

}

void Graphics_view_zoom::set_zoom_factor_base(double value) {

_zoom_factor_base = value;

}

bool Graphics_view_zoom::eventFilter(QObject *object, QEvent *event) {

if (event->type() == QEvent::MouseMove) {

QMouseEvent* mouse_event = static_cast(event);

QPointF delta = target_viewport_pos - mouse_event->pos();

if (qAbs(delta.x()) > 5 || qAbs(delta.y()) > 5) {

target_viewport_pos = mouse_event->pos();

target_scene_pos = _view->mapToScene(mouse_event->pos());

}

} else if (event->type() == QEvent::Wheel) {

QWheelEvent* wheel_event = static_cast(event);

if (QApplication::keyboardModifiers() == _modifiers) {

if (wheel_event->orientation() == Qt::Vertical) {

double angle = wheel_event->angleDelta().y();

double factor = qPow(_zoom_factor_base, angle);

gentle_zoom(factor);

return true;

}

}

}

Q_UNUSED(object)

return false;

}

Usage example:

Graphics_view_zoom* z = new Graphics_view_zoom(ui->graphicsView);

z->set_modifiers(Qt::NoModifier);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值