简述

Graphics View提供了一个平台用于大量自定义 2D 图元的管理与交互框架包括一个事件传播架构支持场景 Scene 中的图元 Item 进行精确的双精度交互功能。Item 可以处理键盘事件、鼠标按下、移动、释放和双击事件同时也能跟踪鼠标移动。

和 Google 地图一样在管理大量 Item 的时候通常需要 View 具有交互平移/缩放/旋转功能。

交互式 QGraphicsView

便于以后复用实现一个交互式 QGraphicsView - InteractiveView。

主要功能包括

平移

方式一鼠标左键按下然后移动

方式二按下上/下/左/右键分别向各个方向移动

缩放

方式一鼠标滚轮向上滚动放大向下滚动缩小

方式二按加号键带 Shift进行放大按减号键缩小

旋转按空格键逆时针旋转回车键顺时针旋转

效果

源码

interactive_view.h

#ifndef INTERACTIVE_VIEW_H

#define INTERACTIVE_VIEW_H

#include

class QWheelEvent;

class QKeyEvent;

class InteractiveView : public QGraphicsView

{

Q_OBJECT

public:

explicit InteractiveView(QWidget *parent = 0);

// 平移速度

void setTranslateSpeed(qreal speed);

qreal translateSpeed() const;

// 缩放的增量

void setZoomDelta(qreal delta);

qreal zoomDelta() const;

protected:

// 上/下/左/右键向各个方向移动、加/减键进行缩放、空格/回车键旋转

void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;

// 平移

void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

// 放大/缩小

void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;

public Q_SLOTS:

void zoomIn(); // 放大

void zoomOut(); // 缩小

void zoom(float scaleFactor); // 缩放 - scaleFactor缩放的比例因子

void translate(QPointF delta); // 平移

private:

Qt::MouseButton m_translateButton; // 平移按钮

qreal m_translateSpeed; // 平移速度

qreal m_zoomDelta; // 缩放的增量

bool m_bMouseTranslate; // 平移标识

QPoint m_lastMousePos; // 鼠标最后按下的位置

qreal m_scale; // 缩放值

};

#endif // INTERACTIVE_VIEW_H

平移速度默认为 1.0可以使用 setTranslateSpeed() 来改变。缩放的增量大小也可以使用 setZoomDelta() 改变。

interactive_view.cpp

#include

#include

#include "interactive_view.h"

#define VIEW_CENTER viewport()->rect().center()

#define VIEW_WIDTH viewport()->rect().width()

#define VIEW_HEIGHT viewport()->rect().height()

InteractiveView::InteractiveView(QWidget *parent)

: QGraphicsView(parent),

m_translateButton(Qt::LeftButton),

m_scale(1.0),

m_zoomDelta(0.1),

m_translateSpeed(1.0),

m_bMouseTranslate(false)

{

// 去掉滚动条

setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

setCursor(Qt::PointingHandCursor);

setRenderHint(QPainter::Antialiasing);

setSceneRect(INT_MIN/2, INT_MIN/2, INT_MAX, INT_MAX);

centerOn(0, 0);

}

// 平移速度

void InteractiveView::setTranslateSpeed(qreal speed)

{

// 建议速度范围

Q_ASSERT_X(speed >= 0.0 && speed <= 2.0,

"InteractiveView::setTranslateSpeed", "Speed should be in range [0.0, 2.0].");

m_translateSpeed = speed;

}

qreal InteractiveView::translateSpeed() const

{

return m_translateSpeed;

}

// 缩放的增量

void InteractiveView::setZoomDelta(qreal delta)

{

// 建议增量范围

Q_ASSERT_X(delta >= 0.0 && delta <= 1.0,

"InteractiveView::setZoomDelta", "Delta should be in range [0.0, 1.0].");

m_zoomDelta = delta;

}

qreal InteractiveView::zoomDelta() const

{

return m_zoomDelta;

}

// 上/下/左/右键向各个方向移动、加/减键进行缩放、空格/回车键旋转

void InteractiveView::keyPressEvent(QKeyEvent *event)

{

switch (event->key()) {

case Qt::Key_Up:

translate(QPointF(0, -2)); // 上移

break;

case Qt::Key_Down:

translate(QPointF(0, 2)); // 下移

break;

case Qt::Key_Left:

translate(QPointF(-2, 0)); // 左移

break;

case Qt::Key_Right:

translate(QPointF(2, 0)); // 右移

break;

case Qt::Key_Plus: // 放大

zoomIn();

break;

case Qt::Key_Minus: // 缩小

zoomOut();

break;

case Qt::Key_Space: // 逆时针旋转

rotate(-5);

break;

case Qt::Key_Enter: // 顺时针旋转

case Qt::Key_Return:

rotate(5);

break;

default:

QGraphicsView::keyPressEvent(event);

}

}

// 平移

void InteractiveView::mouseMoveEvent(QMouseEvent *event)

{

if (m_bMouseTranslate){

QPointF mouseDelta = mapToScene(event->pos()) - mapToScene(m_lastMousePos);

translate(mouseDelta);

}

m_lastMousePos = event->pos();

QGraphicsView::mouseMoveEvent(event);

}

void InteractiveView::mousePressEvent(QMouseEvent *event)

{

if (event->button() == m_translateButton) {

// 当光标底下没有 item 时才能移动

QPointF point = mapToScene(event->pos());

if (scene()->itemAt(point, transform()) == NULL) {

m_bMouseTranslate = true;

m_lastMousePos = event->pos();

}

}

QGraphicsView::mousePressEvent(event);

}

void InteractiveView::mouseReleaseEvent(QMouseEvent *event)

{

if (event->button() == m_translateButton)

m_bMouseTranslate = false;

QGraphicsView::mouseReleaseEvent(event);

}

// 放大/缩小

void InteractiveView::wheelEvent(QWheelEvent *event)

{

// 滚轮的滚动量

QPoint scrollAmount = event->angleDelta();

// 正值表示滚轮远离使用者放大负值表示朝向使用者缩小

scrollAmount.y() > 0 ? zoomIn() : zoomOut();

}

// 放大

void InteractiveView::zoomIn()

{

zoom(1 + m_zoomDelta);

}

// 缩小

void InteractiveView::zoomOut()

{

zoom(1 - m_zoomDelta);

}

// 缩放 - scaleFactor缩放的比例因子

void InteractiveView::zoom(float scaleFactor)

{

// 防止过小或过大

qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();

if (factor < 0.07 || factor > 100)

return;

scale(scaleFactor, scaleFactor);

m_scale *= scaleFactor;

}

// 平移

void InteractiveView::translate(QPointF delta)

{

// 根据当前 zoom 缩放平移数

delta *= m_scale;

delta *= m_translateSpeed;

// view 根据鼠标下的点作为锚点来定位 scene

setTransformationAnchor(QGraphicsView::AnchorUnderMouse);

QPoint newCenter(VIEW_WIDTH / 2 - delta.x(), VIEW_HEIGHT / 2 - delta.y());

centerOn(mapToScene(newCenter));

// scene 在 view 的中心点作为锚点

setTransformationAnchor(QGraphicsView::AnchorViewCenter);

}

这里主要重写了键盘及鼠标事件具体说明请参考注释

qgraphicsview鼠标移动图片_交互式QGraphicsView(平移/缩放/旋转)-阿里云开发者社区...相关推荐

  1. mysql slave是什么_创建slave的搜索结果-阿里云开发者社区

    Rainbond部署Mysql主从集群应用说明 Mysql主从同步原理 1)在Slave 服务器上执行sart slave命令开启主从复制开关,开始进行主从复制. 2)此时,Slave服务器的IO线程 ...

  2. python电子签章_签名python的搜索结果-阿里云开发者社区

    使用C语言扩展Python(一) 开发环境:Ubuntu9.10,python2.6,gcc4.4.1 1,ubuntu下的python运行包和开发包是分开的,因此需要在新利得里面安装python-a ...

  3. mysql inserted表_数据库inserted的搜索结果-阿里云开发者社区

    SQL 2000中的触发器使用 触发器是数据库应用中的重用工具,它的应用很广泛,这几天写一个化学数据统计方面的软件,需要根据采样,自动计算方差,在这里,我使用了触发器. 下面我摘录了SQL Serve ...

  4. abaqus实例手册_《ABAQUS 6.14超级学习手册》——1.6 实例快速入门-阿里云开发者社区...

    本节书摘来自异步社区<ABAQUS 6.14超级学习手册>一书中的第1章,第1.6节,作者: 齐威 更多章节内容可以访问云栖社区"异步社区"公众号查看. 1.6 实例快 ...

  5. 不属于python标准库的是_《Python Cookbook(第2版)中文版》——1.10 过滤字符串中不属于指定集合的字符-阿里云开发者社区...

    本节书摘来自异步社区<Python Cookbook(第2版)中文版>一书中的第1章,第1.10节,作者[美]Alex Martelli , Anna Martelli Ravenscro ...

  6. python实现网站测速软件_网站测速插件是什么-和网站测速插件相关的问题-阿里云开发者社区...

    回2楼ivmmff的帖子 工作太忙了 一口气写不完 ......... 在这里写完了 在移动过去 ------------------------- Re网站加速指南-GoogleAnalytics- ...

  7. 图论 物联网_图论算法-和图论算法相关的内容-阿里云开发者社区

    数学建模需掌握的知识总纲 数学建模需要掌握许多知识,这里我列出总纲: 学建模中的算法 穷举法 神经网络 模拟退火 遗传算法 图论算法 蒙特卡洛算法 所需基础知识 高等数学 线性代数(矩阵加减乘除) 概 ...

  8. qgraphicsview鼠标移动图片_如何在中间鼠标的QGraphicsView中滚动QGraphicsScene?

    我使用pyqt4.8和python2.7 我创建QGraphicsView并插入QGraphicsScene.比View更大的场景,需要滚动.视图有垂直和水平滚动,但我想通过鼠标中键滚动. 我创建鼠标 ...

  9. c#如何wmf图片转换成png图片_【C#】使用fo-dicom完成BMP,JPG,PNG图片转换为DICOM文件-阿里云开发者社区...

    最近研究了一下DICOM和BMP文件转换的问题,也是很头大.度娘了很久,也在CSDN等论坛看到一些断断续续的文件,最主要的是代码只是片断,不是完整的实现.头大了. 首先,了解一下BMP文件格式,BMP ...

最新文章

  1. 成功当选2014年度MVP
  2. .h头文件 .lib库文件 .dll动态链接库文件关系
  3. TikTok广告投放指南(基础入门)
  4. linux平台下rpm方式和源码包方式安装mysql5.7
  5. nginx: [emerg] getpwnam(nginx) failed in /usr/local/nginx/conf/nginx.conf:2
  6. 二维动画作品_「咻动画」二维动画制作中角色造型的设计要点
  7. ip申请 web应用_网络协议端口TCP/IP概览
  8. Ubuntu20.04禁用触摸屏键盘
  9. 【第10章】接口与Lambda表达式
  10. 19.flowable 任务委派
  11. 复旦961-软件工程笔记
  12. 100层摔两个鸡蛋的问题
  13. 苹果cms(mac cms)安装和避雷
  14. 基于MATLAB的图像分割系统
  15. 中文拼写检测(Chinese Spelling Checking)相关方法、评测任务、榜单
  16. 用python做一个上位机串口通信_PYTHON制作画加书法源程序
  17. python做值班表预测_Django model一张表中两个字段设置外键参考另一张表两个字段...
  18. java中instanceof的用法
  19. 关于java8的default关键字浅薄理解
  20. R语言:切换科学计数法和更换小数点位数

热门文章

  1. python中int什么意思_python中int是什么意思
  2. 简述linux中的passwd结构,51CTO博客-专业IT技术博客创作平台-技术成就梦想
  3. 怎么打公式_我们总结了一条抖音爆款公式
  4. web服务器的打开方法_西门子PLC固件升级,S71200 固件升级方法
  5. 如何避免学习linux必然会遇到的几个问题
  6. 【NOIP模拟】矩阵
  7. [NOIP2011] 计算系数(二项式定理)
  8. Flex4 Skinning 1: 自定义一个简单按钮的皮肤
  9. ASP.NET DROPDOWNLIST无刷新联动(中文URL参数处理)
  10. Jupyter中显示数据data时只显示省略号不显示完整数据