Qt浅谈之十八:GraphicsView框架事件处理(有源码下载)
一、简介
GraphicsView支持事件传播体系结构,可以使图元在场景scene中得到提高了已被的精确交互能力。图形视图框架中的事件都是首先由视图进行接收,然后传递给场景,再由场景给相应的图形项。
对于键盘鼠标事件,scene会传递给获得焦点的图形项。如果场景没有获得焦点,那键盘事件会丢弃;如果调用场景setFocus()或者场景中的一个图形项获得了焦点,那么场景会自动获得焦点;如果场景丢失了焦点(如调用clearFocus())而其中一个图形项获得焦点那场景会保存这个图形项的焦点信息。
图形项默认无法接收悬停事件,可以使用QGraphicsItem的setAcceptHoverEvents()函数使图形项可以接收悬停事件。
二、运行图
(1)五个图形项的运行图如下图所示。
三、详解
1、QGraphicsScene
- #ifndef MYSCENE_H
- #define MYSCENE_H
- #include <QGraphicsScene>
- #include <QGraphicsSceneMouseEvent>
- #include <QPaintEvent>
- #include <QKeyEvent>
- class MyScene : public QGraphicsScene
- {
- Q_OBJECT
- public:
- explicit MyScene(QObject *parent = 0);
- protected:
- void keyPressEvent(QKeyEvent *event);
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
- signals:
- public slots:
- };
- #endif // MYSCENE_H
- #include "myscene.h"
- MyScene::MyScene(QObject *parent) :
- QGraphicsScene(parent)
- {
- clearFocus();
- }
- void MyScene::keyPressEvent(QKeyEvent *event)
- {
- qDebug("*********MyScene::keyPressEvent***************");
- return QGraphicsScene::keyPressEvent(event);
- }
- void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
- {
- qDebug("*********MyScene::mousePressEvent***************");
- QGraphicsScene::mousePressEvent(event);
- }
2、QGraphicsView
- #ifndef MYVIEW_H
- #define MYVIEW_H
- #include <QGraphicsView>
- class MyView : public QGraphicsView
- {
- Q_OBJECT
- public:
- explicit MyView(QWidget *parent = 0);
- protected:
- void keyPressEvent(QKeyEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void paintEvent(QPaintEvent * event);
- void mouseMoveEvent(QMouseEvent *event);
- signals:
- public slots:
- };
- #endif // MYVIEW_H
- #include "myview.h"
- #include <QKeyEvent>
- MyView::MyView(QWidget *parent) :
- QGraphicsView(parent)
- {
- }
- void MyView::keyPressEvent(QKeyEvent *event)
- {
- qDebug("*********MyView::keyPressEvent***************");
- switch (event->key())
- {
- case Qt::Key_Left :
- scale(1.2, 1.2);
- break;
- case Qt::Key_Right :
- scale(1 / 1.2, 1 / 1.2);
- break;
- case Qt::Key_Up :
- rotate(30);
- break;
- }
- QGraphicsView::keyPressEvent(event);
- }
- void MyView::mousePressEvent(QMouseEvent *event)
- {
- qDebug("************MyView::mousePressEvent*****************");
- QGraphicsView::mousePressEvent(event);
- }
- void MyView::paintEvent(QPaintEvent *event)
- {
- qDebug("************MyView::paintEvent*****************");
- QGraphicsView::paintEvent(event);
- }
- void MyView::mouseMoveEvent(QMouseEvent *event)
- {
- //qDebug("************MyView::mouseMoveEvent*****************");
- QGraphicsView::mouseMoveEvent(event);
- }
3、QGraphicsItem
- #ifndef MYITEM_H
- #define MYITEM_H
- #include <QGraphicsItem>
- #include <QGraphicsSceneEvent>
- class MyItem : public QGraphicsItem
- {
- public:
- MyItem();
- QRectF boundingRect() const;
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget);
- void setColor(const QColor &color) { brushColor = color; }
- protected:
- void keyPressEvent(QKeyEvent *event);
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
- void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
- void hoverLeaveEvent (QGraphicsSceneHoverEvent * event);
- void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
- void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
- private:
- QColor brushColor;
- };
- #endif // MYITEM_H
- #include "myitem.h"
- #include <QPainter>
- #include <QCursor>
- #include <QKeyEvent>
- #include <QGraphicsSceneHoverEvent>
- #include <QGraphicsSceneContextMenuEvent>
- #include <QMenu>
- MyItem::MyItem()
- {
- brushColor = Qt::red;
- setFlag(QGraphicsItem::ItemIsFocusable);
- setFlag(QGraphicsItem::ItemIsMovable);
- //setAcceptHoverEvents(true);
- }
- QRectF MyItem::boundingRect() const
- {
- qreal adjust = 0.5;
- return QRectF(-10 - adjust, -10 - adjust,
- 20 + adjust, 20 + adjust);
- }
- void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget)
- { qDebug("************MyItem::paint*****************");
- if(hasFocus()) {
- painter->setPen(QPen(QColor(255,255,255,200)));
- } else {
- painter->setPen(QPen(QColor(100,100,100,100)));
- }
- painter->setBrush(brushColor);
- painter->drawRect(-10, -10, 20, 20);
- }
- // 鼠标按下事件处理函数,设置被点击的图形项获得焦点,并改变光标外观
- void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
- {
- qDebug("************MyItem::mousePressEvent*****************");
- setFocus();
- setCursor(Qt::ClosedHandCursor);
- }
- // 键盘按下事件处理函数,判断是否是向下方向键,如果是,则向下移动图形项
- void MyItem::keyPressEvent(QKeyEvent *event)
- {
- qDebug("************MyItem::keyPressEvent*****************");
- if(event->key() == Qt::Key_Down)
- moveBy(0, 10);
- }
- // 悬停事件处理函数,设置光标外观和提示
- void MyItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
- {
- qDebug("************MyItem::hoverEnterEvent*****************");
- setCursor(Qt::OpenHandCursor);
- setToolTip("I am item");
- }
- void MyItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
- {
- qDebug("************MyItem::hoverLeaveEvent*****************");
- setCursor(Qt::ArrowCursor);
- }
- // 右键菜单事件处理函数,为图形项添加一个右键菜单
- void MyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
- {
- QMenu menu;
- QAction *moveAction = menu.addAction("move back");
- QAction *actAction = menu.addAction("test");
- QAction *selectedAction = menu.exec(event->screenPos());
- if(selectedAction == moveAction) {
- setPos(0, 0);
- }
- }
- void MyItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
- {
- qDebug("************MyItem::mouseMoveEvent*****************");
- QGraphicsItem::mouseMoveEvent(event);
- }
4、main及运行
- #include <QApplication>
- #include "myitem.h"
- #include "myview.h"
- #include "myscene.h"
- #include <QTime>
- int main(int argc,char* argv[ ])
- {
- QApplication app(argc,argv);
- qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
- MyScene scene;
- scene.setSceneRect(-200, -150, 400, 300);
- for(int i = 0; i < 5; ++i) {
- MyItem *item = new MyItem;
- item->setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
- item->setPos(i * 50 - 90, -50);
- scene.addItem(item);
- }
- MyView view;
- view.setScene(&scene);
- view.setBackgroundBrush(QPixmap(":/background.png"));
- view.show();
- return app.exec();
- }
分析:keyPressEvent键盘按下事件由View—Scene—Item
分析:mousePressEven鼠标按下事件由View—Scene—Item
分析:事件项Item没有获得焦点时,mousePressEven鼠标按下事件只由View传递到Scene。
分析:事件项Item的悬停事件,在构造函数中设置了setAcceptHoverEvents(true)。
四、总结
(1)本文只是GraphicsView框架事件处理的部分测试数据解析,若对其他的事件感兴趣可以下载本代码进行自己的测试开发工作。
(2)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/7786371)。
(3)本人思路有限,若有更好的设计建议,也可发邮件沟通,在此先感谢!邮箱地址yang.ao@i-soft.com.cn。
http://blog.csdn.net/taiyang1987912/article/details/38686361
Qt浅谈之十八:GraphicsView框架事件处理(有源码下载)的更多相关文章
- Qt浅谈之四十九俄罗斯方块(代码来自网络)
一.简介 从网上下载了一个Qt实现的俄罗斯方块单机版的源码,觉得非常有意思,故以博客形式记录下来,以便慢慢来研究.在centos6.6下编译运行(注意程序运行需要读取pro目录的配置文件,若把编译目录 ...
- Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口
一.简介 最近看到一篇Qt实现伸缩滑动的窗口的文章,但其代码不完整.便在此重新书写了完整的代码,并开源出来.窗口的中央有滑动条可以动态改变子窗口的大小,隐藏的按钮可以快速伸缩子窗口.其效果图如下: 二 ...
- Qt浅谈之三十九圆形进度条(已经有50篇了)
http://blog.csdn.net/taiyang1987912/article/category/2314763
- Qt浅谈内存泄露(总结)
Qt浅谈内存泄露(总结) 来源 http://blog.csdn.net/taiyang1987912/article/details/29271549 一.简介 Qt内存管理机制:Qt 在内部能够维 ...
- Qt浅谈之总结(整理)
Qt浅谈之总结(整理) 来源 http://blog.csdn.net/taiyang1987912/article/details/32713781 一.简介 QT的一些知识点总结,方便以后查阅. ...
- 浅谈Python Web的五大框架
说到Web Framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界.各种micro-framework.framework不可胜数. 尽管还有一大脚本语言PHP也有 ...
- Qt浅谈之二十App自动重启及关闭子窗口
一.简介 最近因项目需求,Qt程序一旦检测到错误,要重新启动,自己是每次关闭主窗口的所有子窗口但有些模态框会出现问题,因此从网上总结了一些知识点,以备以后的应用. 二.详解 1.Qt结构 int ma ...
- Qt浅谈之二十App自动重启及关闭子窗口(六种方法)
一.简介 最近因项目需求,Qt程序一旦检测到错误,要重新启动,自己是每次关闭主窗口的所有子窗口但有些模态框会出现问题,因此从网上总结了一些知识点,以备以后的应用. 二.详解 1.Qt结构 int ma ...
- Qt浅谈之二十六图片滑动效果
一.简介 博客中发现有作者写的仿360的代码,觉得其中图片滑动的效果很有意思,特提取其中的代码.并加上类似mac的画面移动的动画效果. 二.详解 1.代码一:界面滑动(QWidget) (1)slid ...
随机推荐
- Delegates, Events and Singletons with Unity3D – C#
在这里我将演示怎样创建代表. 事件和Singletons 在一起工作. 本教程为 Unity3D 编写. 我想知道这为什么?作为一个年轻的自学程序猿,我常常发现自己写tons 和布尔的语句,以确 ...
- 公钥,私钥和数字签名这样最好理解 分类: B3_LINUX 2015-05-06 16:25 59人阅读 评论(0) 收藏
一.公钥加密 假设一下,我找了两个数字,一个是1,一个是2.我喜欢2这个数字,就保留起来,不告诉你们(私钥),然后我告诉大家,1是我的公钥. 我有一个文件,不能让别人看,我就用1加密了.别人找到了这个 ...
- keil出现蓝色小箭头
- 8、摄像头驱动_Linux的V4L2架构分析
V4L2架构可以参考 linux-3.4.2\Documentation\video4linux\v4l2-framework.txt V4L2全名为Video For Linux 2,它是针对Li ...
- 【BZOJ 4518】[Sdoi2016]征途
[链接] 链接 [题意] 在这里输入题意 [题解] DP+斜率优化; \(D(x) = E(x^2)-E(x)^2\) 其中\(E(x)^2\)这一部分是确定的. 因为总长是确定的,分成的段数又是确定 ...
- 调试 之gdb thread命令 与 ltrace/strace
我们可以通过 1) gdb prog_name -> r 用在逐步调试自己的程序时 2) gdb -> attach process_id 正 ...
- “locktype”enum type 类型重定义问题的解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 使用ado来连接数据库,结果出现这样一些编译错误: 1>f:\c++pro\iocptser\debug\msa ...
- 使用ionic3快速开发webapp(一)
Ionic可以让我们使用web技术快速构建接近原生体验的跨平台移动应用. 一.安装ionic 1.需要先安装 Node.js(版本8.x之上): 2.安装cordova 和 ionic: $ npm ...
- putty-gns3
hcl-cloud用的就是这个putty http://forum.gns3.net/topic5016.html File comment: Compiled PuTTY 0.62 for wind ...
- [Elm] Functions in Elm
Functions are an important building block in Elm. In this lesson we will review stateless functions, ...