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

来源:互联网 发布:浙江软件考试成绩查询 编辑:程序博客网 时间:2024/05/18 01:21

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_OBJECTpublic: 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/ 
0 1
原创粉丝点击