QTGraphics-View拖拽以及鼠标指针操作
因为QGraphicsView继承自QWidget,它也提供了像QWidget那样的拖拽功能。
另外,为了方便,Graphics View框架也为场景以及每个item提供拖拽支持。当视图接收到拖拽事件,它可转化为QGraphicsSceneDragDropEvent,再发送到场景。场景接管这个事件,把它发送到光标下接受拖拽的第一个item。 从一个item开始拖拽时,创建一个QDrag对象,传递开始拖拽的那个widget的指针。Items可以同时被多个视图观察,但只有一个视图可以开始拖拽。
拖拽在多数情况下是从按下鼠标或是移动鼠标开始的,因此,在 mousePressEvent()或mouseMoveEvent()中,你可以从事件中得到那个原始的widget指针,例如:
|
1
2 3 4 5 6 7 8 |
void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ QMimeData *data = new QMimeData; data->setColor(Qt::green); QDrag *drag = new QDrag(event->widget()); drag->setMimeData(data); drag->start(); } |
为了在场景中获取拖拽事件,你应重新实现QGraphicsScene::dragEnterEvent()和在QGraphicsItem的子类里任何与你特定场景需要的事件处理器。items也可以通过调用QGraphicsItem::setAcceptDrops()获得拖拽支持,为了处理将要进行的拖拽,你需要重新实现QGraphicsItem::dragEnterEvent(),QGraphicsItem::dragMoveEvent(),QGraphicsItem::dragLeaveEvent()和QGraphicsItem::dropEvent()。
像QWidget一样,QGraphicsItem也支持光标(QgraphicsItem::setCursor)与工具提示(QGraphicsItem::setToolTip())。当光标进入到item的区域,光标与工具提示被QGraphicsView激活(通过调用QGraphicsItem::contains()检测)。你也可以直接在视图上设置一个缺省光标(QGraphicsView::setCursor)。
Qt自带例程Drag and Drop Robot介绍了这两方面的内容。

在这个demo中,可以把机器人四周的颜色拖动到机器人的各个部位,比如说头,臂,身躯等,然后这个部位就会变成相应的颜色,类似于换装小游戏。
下图是经过我的一番操作后的机器人模样:

以下是我学习这个Demo的一些知识总结,仅供交流学习,如有错误,欢迎指正,一起进步:
圆形颜色图元ColorItem
随机颜色值:), ), ));
Tooltips:setToolTip(QString("QColor(%1, %2, %3)\n%4").arg(color.red()).arg(color.green()).arg(color.blue()).arg("Click and drag this color onto the robot!"));
鼠标移入图元手势 (展开的小手):setCursor(Qt::OpenHandCursor);
- 绘制(两个组合圆):
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::darkGray);
painter->drawEllipse(-12,-12, 30, 30);
painter->setPen(QPen(Qt::black, 1));
painter->setBrush(QBrush(color));
painter->drawEllipse(-15,-15, 30, 30);
鼠标左键按下:setCursor(Qt::ClosedHandCursor);
鼠标左键释放:setCursor(Qt::OpenHandCursor);
鼠标左键移动过程(主要逻辑):
// 需要有一个最小移动距离限制(10px)
if(QLineF(event->screenPos(), event->buttonDownScreenPos(Qt::LeftButton))
.length()< QApplication::startDragDistance()) {
return;
}
// 创建拖动对象,并绑定一个MIME数据
QDrag*drag= new QDrag(event->widget());
QMimeData*mime= new QMimeData;
drag->setMimeData(mime);
PS:QMimeData is used to describe information that can be stored in the clipboard, and transferred via the drag and drop mechanism.
QMimeData objects are usually created using new and supplied to QDrag or QClipboard objects.
对于从刚初始化后两次以上的拖动,可能会出现人脸的图像,其余情况则是对原始圆形图元的拖动。
设置MIME图像数据: QMimeData::setImageData
设置MIME纯文本数据: QMimeData::setText
设置MIME颜色数据: QMimeData::setColorData
设置拖动热点: QDrag::setHotSpot
设置拖动过程中的图像: QDrag::setPixmap
执行拖动: QDrag::exec();
既然有了拖动(Drag),就得有接收拖动的地方,即释放拖动的地方(Drop)。在本Demo中,执行Drop操作的主体是中间的摇摆机器人Robot。
首先需要使能Drop:setAcceptDrops(true);
具体需要重载以下三个关于Drag-Drop的虚函数:
void dragEnterEvent(QGraphicsSceneDragDropEvent*event) override;
void dragLeaveEvent(QGraphicsSceneDragDropEvent*event) override;
void dropEvent(QGraphicsSceneDragDropEvent*event) override;
其中QGraphicsSceneDragDropEvent类携带了拖动的mime数据信息,通过bool类型成员变量dragOver标识拖动是否移动到机器人身体上,移入则响应dragEnterEvent(颜色加亮显示),移出则响应dragLeaveEvent,并置位dragOver。
释放操作则响应dropEvent,将传递过来的颜色值赋给当前QPainter画刷颜色,调用update来调用paint函数重新绘制。
如果头像移入头部则绘制头像图片。
所有机器人的各部件(头、胳膊、躯干)通过Robot类整体组织起来,并加上了动画。
Rebort不进行任何paint操作:setFlag(ItemHasNoContents);
PS:The item does not paint anything (i.e., calling paint() on the item has no effect). You should set this flag on items that do not need to be painted to ensure that Graphics View avoids unnecessary painting preparations.
Robot各部位Item的排序:

其中,躯干是Root Item(所有其他Item是children或躯干的后代),因此首先绘制(1)。 接下来,绘制头部(2),因为它是躯干children列表中的第一个项目。 然后绘制左上臂(3), 由于下臂是上臂的孩子,因此下臂被拉动(4),接着是上臂的下一个兄弟,即右上臂(5),依此类推。
头部动画(旋转和缩放属性):
QPropertyAnimation*headAnimation= new QPropertyAnimation(headItem, "rotation");
QPropertyAnimation*headScaleAnimation= new QPropertyAnimation(headItem, "scale");
其余部位的动画类似…
所有的QPropertyAnimation通过QParallelAnimationGroup组合在一起并行运行。
QParallelAnimationGroup*animation= new QParallelAnimationGroup(this);
animation->addAnimation(headAnimation);
animation->addAnimation(headScaleAnimation);
最后,让我们继续摇摆:

QTGraphics-View拖拽以及鼠标指针操作的更多相关文章
- View拖拽 自定义绑定view拖拽的工具类
由于工作需求,需要用到这种处理方法所以我就写了这个 废话不多说先看效果图 接下来就看代码吧 DragDropManager import android.app.Activity; import an ...
- IOS view拖拽(触摸事件)
• iOS中的事件可以分为3大类型 触摸事件 加速计事件 远程控制事件 响应者对象 • 在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事 件.我们称之为“响应 ...
- 使用 Jquery-UI 实现一次拖拽多个选中的元素操作
项目需要,实现一个拖放操作,要求每次可以拖拽选中的多个元素,释放到目标容器后可排序.考虑了一下,觉得jquery-ui比较合适,毕竟它提供了项目需要的交互性事件机制.拖拽.释放.排序.选择等效果.而在 ...
- (原创)[C#] 一步一步自定义拖拽(Drag&Drop)时的鼠标效果:(一)基本原理及基本实现
一.前言 拖拽(Drag&Drop),属于是极其常用的基础功能. 无论是在系统上.应用上.还是在网页上,拖拽随处可见.同时拖拽时的鼠标效果也很漂亮,像这样: 这样: 还有这样: 等等等等. 这 ...
- 完美实现鼠标拖拽事件,解决各种小bug,基于jquery
鼠标拖拽事件是web中使用频率极高的事件,之前写过的代码包括网上的代码,总存在各种各样的问题,包括拖拽体验差,松开鼠标后拖拽效果仍存在以及代码冗余过大等 本次我才用jQuery实现一个尽可能高效的拖拽 ...
- Image 鼠标拖拽与鼠标中键的缩放
一.Image在窗体上拖拽,势必会用到鼠标的三个事件(MouseDown,MouseUp,MouseMove),以左键为例,PictureBox为载体 Point mouseDownPoint = n ...
- html5 Sortable.js 拖拽排序源码分析
最近公司项目经常用到一个拖拽 Sortable.js插件,所以有空的时候看了 Sortable.js 源码,总共1300多行这样,写的挺完美的. 本帖属于原创,转载请出名出处. 官网http:// ...
- JS组件系列——Bootstrap Table 表格行拖拽
前言:之前一直在研究DDD相关知识,好久没更新JS系列文章了.这两天做了一个简单的业务需求,觉得效果还可以,今天在这里分享给大家,欢迎拍砖~~ 一.业务需求及实现效果 项目涉及到订单模块,那天突然接到 ...
- Winform图片拖拽与缩放
最近做项目的时候遇到上传施工平面布置图,查看,因为图片比较大,一般的显示器分辨率无法显示全,然后还需要放大看清楚图片里面的文字内容,所以需要用到图片的拖拽与缩放功能.这里整理下具体操作. 首先新建一个 ...
随机推荐
- classpath环境变量解惑
只有使用低于JDK1.5版本的JDK时,才需要设置classpath环境变量. 因为早期版本的JDK没有设计在当前路径下搜索Java类的功能,而且编译和运行java程序时还需要JDK的lib路径下的d ...
- NOIP 2013 积木大赛
洛谷 P1969 积木大赛 洛谷传送门 JDOJ 2229: [NOIP2013]积木大赛 D2 T1 JDOJ传送门 题目描述 春春幼儿园举办了一年一度的"积木大赛".今年比赛的 ...
- eclipse export runnable jar(导出可执行jar包) runnable jar可以执行的
如果要导出可运行的JAR文件,需要选择Runnable Jar File. 1. 选择要到处JAR文件的工程,右键选择“Export”: 2. 选择“Java-->Runnable JAR fi ...
- Redis有哪些数据结构
String 这应该是应用最广泛的了,简单的 key-value 类型.value 不仅可以是 String,也可以是数字.还可以享受 Redis 的定时持久化(可以选择 RDB 模式或者 AOF 模 ...
- Qt绘制中国象棋棋盘
这里主要用的是#include <QPainter>里面的paintEvent void Board::paintEvent(QPaintEvent*) { QPainter painte ...
- Python内置函数---ord()
描述: ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCI ...
- connect ECONNREFUSED 127.0.0.1:80错误解决
这个报错也是一直困扰了我许久,服务端一直打印这个报错,但是页面数据响应又都正常,起初真不知道是因为什么原因,能看出来他是在调用80端口, 但是不明白为什么会调用80端口.一度以为是config.js里 ...
- 石锤了!google彻底断供华为,只能加速鸿蒙生态的形成
前言 操作系统是当今科技行业的灵魂,而即将推出这款操作系统是一个集电脑.手机.汽车等设备于一体的系统.如今手机行业里已经是一片红海了,竞争相当激烈,但是竞争归竞争,但是一旦扯上别的事就更麻烦了,像华为 ...
- web前端图片模糊到清晰的实现过程
在网页图片显示的时候,会发现许多网站采用了先模糊,然后在慢慢清晰的过程,这样的加载用户体验是比较好的,那么如何实现? 默认加载2张图片,一张缩略图,一张原图,当打开网页的时候默认只显示缩略图,然后我们 ...
- cad.net 读取pc3,pmp 读取pc3打印机文件
修改pc3文件还没做好..大家先look look怎么读.... 首先弄一个控制台程序, 然后去下载 Ionic.Zip 这个东西...载到控制台...都很简单... 然后就是复制下面代码,看控制台显 ...