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

2023-11-30

我有一个应用程序QGraphicsView窗口位于屏幕中间。我希望能够使用鼠标滚轮滚动来放大和缩小。

目前我已经重新实现了QGraphicsView并覆盖鼠标滚动功能,以便它不会滚动图像(就像默认情况下一样)。

void MyQGraphicsView::wheelEvent(QWheelEvent *event)
{
    if(event->delta() > 0)
    {
        emit mouseWheelZoom(true);
    }
    else
    {
        emit mouseWheelZoom(false);
    }
}

因此,当我滚动时,如果鼠标滚轮向前,我会发出一个信号 true;如果鼠标滚轮向后,我会发出一个信号 false。

然后我将此信号连接到一个插槽(缩放功能见下文)在处理我的 GUI 内容的类中。现在基本上我认为我的缩放功能根本不是最好的方法,我已经看到了一些人们使用覆盖的wheelevent函数来设置比例的例子,但我真的找不到完整的答案。

因此,我已经这样做了,但它无论如何都不完美,所以我正在寻找对此进行一些调整,或者寻找在轮事件函数中使用比例的工作示例。

我初始化m_zoom_level to 0在构造函数中。

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 并将转换锚点设置为鼠标下方,但有时如果我滚动负载,它只会开始放大(我认为这与 int 循环有关)结束什么的)。

正如我所说,对此提供帮助或在鼠标下缩放的一个很好的例子会很棒。


这种缩放有点棘手。让我分享一下我自己的课程。

Header:

#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();
};

Source:

#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);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QGraphicsView 使用鼠标滚轮在鼠标位置下放大和缩小 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • 如何使用 C# 中的参数将用户重定向到 paypal

    如果我有像下面这样的简单表格 我可以用它来将用户重定向到 PayPal 以完成付款
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐

  • 命名空间和类同名吗?

    我正在组织一个图书馆项目 并且有一个名为的中央管理器类Scenegraph以及位于 Scenegraph 命名空间中的一大堆其他类 我真正想要的是场景图MyLib Scenegraph和其他类别MyLib Scenegraph 但似乎唯一的
  • AngularJS UI-Router:在应用程序加载之前预加载 $http 数据

    我需要使用过 ui router 插件的 AngularJS 专家的帮助 有人可以提供一个在应用程序运行之前预加载 http 数据请求的 plunker 示例吗 我做了一些研究 但最接近的是这两个堆栈溢出 AngularJS 如何在应用程序
  • Java程序禁用SSL认证存在安全风险

    我们的团队会抓取网站以使我们的信息保持最新 我遇到了抓取HTTPS页面时的安全异常 问题在于 Java 在接受页面自签名证书时存在问题 我没有保留要接受的证书列表 将来可能很难维护 而是使用 neu242 提供的解决方法来禁用 SSL 证书
  • 在运行时将 C# 标签添加到表单

    我正在尝试用 C 制作一个简单的基于文本的游戏 我想实现这一点的方法是向表单添加标签 而不是使用命令提示符 我在将它们添加到屏幕时遇到一些问题 Visual Studio 给出了一个未指定的错误 只是说我有一个未处理的异常 你调用的对象是空
  • 如何去除抽屉上方的台阶

    我在用着DaisyUI and 顺风CSS 我正在使用一个drawer and steps div class drawer div
  • 在托管类中调用非托管函数时出现 C++/CLI System.AccessViolationException

    我在 C 中有一个本机回调函数 让我们这样说 void CallbackFunction void Do nothing 现在我有另一个本机函数 void SomeNativeFunction void m callback std tr1
  • 终止子进程时终止所有(孙)子进程

    我将直接进入 简短且具有描述性 C Windows API 我正在使用创建子进程CreateProcess运行外部 命令行 应用程序 我已经内置了一个超时 如果到那时子进程还没有返回正常执行 我希望强制终止该子进程 理想情况下 我希望该子进
  • 如何使用 ASP.NET 身份模型进行 WCF 服务授权和身份验证

    我正在开发一个 ASP NET 4 5 Web 应用程序 它使用 ASP NET 身份模型进行身份验证和授权 该 Web 应用程序还托管 WCF 服务并同时使用它 还有另一个基于 WPF 的应用程序将使用托管的 WCF 服务 以及作为客户端
  • 如何减少 YOLOv3 文件中的类数量?

    我正在使用 YOLOv3 来检测视频中的汽车 我下载了代码中使用的三个文件coco names yolov3 cfg and yolov3 weights它们针对 80 种不同类别的待检测物体进行了训练 该代码可以运行 但速度非常慢 每帧需
  • 如何使用 YouTube Android 播放器 API 播放 YouTube 直播?

    我已经成功使用 YouTubePlayer 播放 YouTube 视频 但是 当我尝试使用 YouTubePlayer 播放直播时 没有任何反应 API支持直播吗 如果是这样 我该怎么做 播放普通 YouTube 视频和直播视频没有区别 我
  • (psycopg2.DataError) 整数输入语法无效:从 csv 文件导入?

    我的csv文件中的数据是这样的 081299289X China Dolls Lisa See 2014 0345498127 Starter for Ten David Nicholls 2003 0061053716 Imajica C
  • python np.nan 和 '==' & 'is' [重复]

    这个问题在这里已经有答案了 当我检查 Python 操作数的相等性和同一性时 例如a b a我明白了 a b gt True a is b gt True 我明白了 那么 为什么我得到 np nan 的 diff 结果 a np nan b
  • IsDate 函数返回意外结果

    怎么会IsDate 13 50 回报True but IsDate 12 25 2010 回报False 我最近被这个小 功能 绊倒了 想提高人们对围绕该功能的一些问题的认识 IsDateVB 和 VBA 中的函数 简单的案例 正如你所期望
  • 从具有级别的列表构造一棵树

    我有一些数据 Pythonlist of dicts 看起来像 value A level 0 value B level 1 value C level 2 value D level 1 value E level 2 value F
  • Apache Poi:从 HSSF 转换为 SS?

    除了我制作工作簿的部分之外 我已将 HSSF 中的所有旧代码转换为 SS 旧代码 HSSFWorkbook wb new HSSFWorkbook new FileInputStream 文件 新的非工作代码 工作簿 wb2 新工作簿 新F
  • Django, sorl-缩略图裁剪图片头像

    伙计们 我想知道 sorl thumbnail 是否有任何选项可以从下到上裁剪 我有一个垃圾问题 在某些图片中 sorl thumbnail 正在裁剪图片中人物的头部 Thanks 我刚刚发布了新版本的 sorl thumbnail 3 2
  • Java中如何检查字符串中是否包含日期?

    如何检查字符串是否包含以下形式的日期 美国东部时间 2012 年 1 月 15 日星期日晚上 7 36 我正在处理的数据包含大量字符串 但我正在寻找的字符串类型包含 2 或 3 个单词的名称和日期 我正在检查日期来识别这些类型的字符串 我已
  • 使用 Pandas 修改 Excel 文件,布局变化最小

    我已经读过Pandas 可以读取和修改单个 Excel 文件工作表 选项卡 而不修改文件的其余部分吗 但在这里我的问题是针对下文提到的布局的 如何使用 Pandas 打开 Excel 文件 进行一些修改 然后将其保存回来 1 不删除有一个F
  • PhoneGap - 使 Android 功能成为可选

    我希望为我的 Android 应用程序设置一些不需要的设置 以便 Google 的 Play 商店会识别它对平板电脑也有用 我需要将这两行添加到我的 AndroidManifest xml 中
  • QGraphicsView 使用鼠标滚轮在鼠标位置下放大和缩小

    我有一个应用程序QGraphicsView窗口位于屏幕中间 我希望能够使用鼠标滚轮滚动来放大和缩小 目前我已经重新实现了QGraphicsView并覆盖鼠标滚动功能 以便它不会滚动图像 就像默认情况下一样 void MyQGraphicsV