QGraphicsView放大和缩小下鼠标位置使用鼠标滚轮

转载 2016年08月31日 16:57:35

c++ qt qgraphicsview
我有一个在屏幕中间的QGraphicsView窗口的应用程序。我想能够放大和车轮滚动。 目前,我有重新的QGraphicsView和重写的滚动函数,让是doesnt滚动图像(像它在默认情况下)。
void MyQGraphicsView::wheelEvent(QWheelEvent *event)
{
 if(event->delta() > 0)
 {
  emit mouseWheelZoom(true);
 }
 else
 {
  emit mouseWheelZoom(false);
 }
}
所以,当我滚动IMlaunch的信号是当轮着假,如果回轮。 我曾那么这个信号连接到一个槽(变焦函数见下文)在处理我的GUI的东西类。现在基本上我觉得我的变焦函数只是心不是这样做的重写wheelevent函数的所有IV看到的例子来设置秤的最佳方式,但我不可能真正找到答案。 所以不是我有这么即时寻找这个做到了这一点,但它的不完美被扭捏了一下 CodeGo.net,或在滚轮事件函数的工作规模。 í初始化m_zoom_level0在构造函数中。
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);
 }
}
正如你可以看到上面有QMatrix和标定,并设置为Graphicsview和转换锚点设置下,但它只是不工作完美,如果IM滚动加载它只是开始放大只(我认为这是做的诠释循环或以上 正如我所说的帮助,这还是规模下一个很好的例子将是巨大的感谢
本文地址 :CodeGo.net/8897373/ 
------------------------------------------------------------------------------------------------------------------------- 
1.这种缩放是有点棘手。分享我自己的类做的。 包头:
#include <QObject>
#include <QGraphicsView>
/*!
 * 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();
};
来源:
#include "Graphics_view_zoom.h"
#include <QMouseEvent>
#include <QApplication>
#include <QScrollBar>
#include <qmath.h>
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<QMouseEvent*>(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<QWheelEvent*>(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;
}
用法示例:
Graphics_view_zoom* z = new Graphics_view_zoom(ui->graphicsView);
z->set_modifiers(Qt::NoModifier);

2. 经过一番这似乎工作。这个问题似乎是,该QGraphicsViewtransform无关,其滚动的位置,所以行为QGraphicsView::mapToScene(const QPoint&) const依赖于两个涡旋盘的位置和变换。我看源代码mapToScene要明白这一点。 考虑到这一点,这里有什么工作:现场点的指向,缩放,地图的场景点的坐标 CodeGo.net,然后将滚动条,使该点风下
void ZoomGraphicsView::wheelEvent(QWheelEvent* event)
{
 const QPointF p0scene = mapToScene(event->pos());
 qreal factor = std::pow(1.01, event->delta());
 scale(factor, factor);
 const QPointF p1mouse = mapFromScene(p0scene);
 const QPointF move = p1mouse - event->pos(); // The move
 horizontalScrollBar()->setValue(move.x() + horizontalScrollBar()->value());
 verticalScrollBar()->setValue(move.y() + verticalScrollBar()->value());
}

3. 这是一个有点晚 但我走过的今天,只有用Pyside,但应该是 这种方法是“非常简单”,altough位 首先将所有锚NoAnchor,然后采取wheelevent点,其映射到现场, 翻译现场由这个值,规模,最后转换回:
def wheelEvent(self, evt):
 #Remove possible Anchors
 self.widget.setTransformationAnchor(QtGui.QGraphicsView.NoAnchor)
 self.widget.setResizeAnchor(QtGui.QGraphicsView.NoAnchor)
 #Get Scene Pos
 target_viewport_pos = self.widget.mapToScene(evt.pos())
 #Translate Scene
 self.widget.translate(target_viewport_pos.x(),target_viewport_pos.y())
 # ZOOM
 if evt.delta() > 0:
  self._eventHandler.zoom_ctrl(1.2)
 else:
  self._eventHandler.zoom_ctrl(0.83333)
 # Translate back
 self.widget.translate(-target_viewport_pos.x(),-target_viewport_pos.y())

这是工作了我的目的,唯一的解决办法。
恕我直言,这也是最符合逻辑的解决方案...

4.
这给出了在最佳的一个非常经验,并且应该避免。有一个很好的理由,为什么它不是Qt提供一个默认的行为。没关系,你不会有任何人的人机界面指南-您的应用程序不会使其进入Mac App Store的,亦不会为Windows应用商店。就个人而言,我会打电话给你的应用程序中断。
 当人们想放大,它们具有输入,做到这一点的输入装置。在触控板和触摸屏,捏的手势是有你,和Qt不支持它。在小鼠中,您可能需要一个独立的变焦轮,或至少一个修饰键。即使是这样,我不觉得这是一个好主意,因为你遇到了“有趣”的一角情况下,当调节剂被释放,但驱动程序或操作系统生成惯性运动的滚轮。你至少需要禁用惯性您的应用程序。到目前为止,我知道怎么做了OS X上,但我不知道如何将一个做到这一点在Windows上。
 如果任何人有掐输入的输入设备,应用程序将打破。你是不是处理双指缩放,从触摸屏(认为微软表面Pro或其他可转换债券)或触控板。您也将滚动投入缩放输入。你觉得这有什么意义可言了每一寸其他应用重新定义很可能你的平台(除了谷歌地图)上运行。
 顶多这应该是一个可选的解决方法的人太便宜,以获得更好,应该在默认情况下处于关闭状态。
 总体来说,我还没有看到任何人它正确,它真的不能正确完成。
 在正确的位是超重要。让我们来谈谈日常恐怖预告:谷歌地图。所以,要滚动地图,你不断地结束了放大,然后等待愚蠢的事情来重新加载等,这是一个扎实坏主意,因为滚轮/触控板的一切,但不幸的谷歌地图左右滚动。他们也有过缩放滚轮无法控制,所以对小鼠/触控板,它的行为合理,别人只是吹起来,以最大或最小缩放级别如此之快没有办法来控制它。他们在想什么。并非所有的流行的是什么好。
 注意:对于一个给定平台的人机界面指南是有原因的。即使你不打算发布您的产品到应用商店,你会迷失方向由逆着人流那里。这是糟糕的设计。我还是恳请你不要做。你可能不关心应用程序商店,但你不关心为好。
 让我们不要忘记,有横向和纵向滚轮事件。这将是你放大垂直滚轮运动起来,而是让通过横向的事件,他们会妥善任何滚动QAbstractScrollAreaQGraphicsView。
 哦,你确定你是妥善处理或禁用滚轮惯性?

本文标题 :的QGraphicsView放大和缩小下鼠标位置使用鼠标滚轮

本文地址 :CodeGo.net/8897373/ 

相关文章推荐

交互式QGraphicsView(平移/缩放/旋转)

Graphics View提供了一个平台,用于大量自定义 2D 图元的管理与交互,框架包括一个事件传播架构,支持场景 Scene 中的图元 Item 进行精确的双精度交互功能。Item 可以处理键盘...

QGraphicsView类

QGraphicsView提供一个显示QGraphicsScene内容的窗口,该窗口可以滚动,可以在构造时候把场景对象作为参数,或者之后使用setScene()来设置view的场景,然后调用了show...

QGraphicsView用法总结

用以展示QGraphicsScene对象 QGraphicsView可以展示QGraphicsScene的全部,也可以展示其一部分 QGraphicsScene scene; scene.ad...

Qt 在GraphicsView中 打开一幅图片

简述: 记录一下如何在 Qt中打开一幅图片 步骤: 1. 新建一个项目,Qt C++ 项目, Qt GUI应用 之后按步骤新建就可以了, 2. 勾选中下面这三个...
  • anialy
  • anialy
  • 2012年11月14日 01:08
  • 26101

GraphicsView的旋转,放缩

视图可以通过矩阵 QMatrix 设置放缩,旋转; 在Qt , GDI+等多种绘图方式中,矩阵方式概念变化图像,是图像变化的一种高级方式; // extern GraphicsView *   g...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Qt中窗体控件按照比例缩放,自适应窗口大小进行布局

最近在做本科毕设,用到了Qt,无奈本人实在是太过于小白了,很多东西都进行了很久的探索,比如今天说到的窗体控件布局...一把辛酸泪     首先就是创建一个GUI文件,然后进行UI设计,这里就只需要从左...

Qt浅谈之十八:GraphicsView框架事件处理

一、简介        GraphicsView支持事件传播体系结构,可以使图元在场景scene中得到提高了已被的精确交互能力。图形视图框架中的事件都是首先由视图进行接收,然后传递给场景...

如何使QGraphicsItem不随QGraphicsView放大缩小而改变大小

一、简述在使用QGraphicsView过程中,有时候我们需要对view进行缩放,但是对于一般正常的加入view中的item都会随着view的大小变化而变化,但是如果我们想让某些item不随view的...

QT画线教程(GraphicsViewFramework)

现在基本上也已经到了2D绘图部分的尾声,所谓重头戏都是在最后压轴的,现在我们就要来看看在绘图部分功能最强大的Graphics View。我们经常说KDE桌面,新版本的KDE桌面就是建立在Graphic...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:QGraphicsView放大和缩小下鼠标位置使用鼠标滚轮
举报原因:
原因补充:

(最多只允许输入30个字)