一、简介

GraphicsView支持事件传播体系结构,可以使图元在场景scene中得到提高了已被的精确交互能力。图形视图框架中的事件都是首先由视图进行接收,然后传递给场景,再由场景给相应的图形项。

对于键盘鼠标事件,scene会传递给获得焦点的图形项。如果场景没有获得焦点,那键盘事件会丢弃;如果调用场景setFocus()或者场景中的一个图形项获得了焦点,那么场景会自动获得焦点;如果场景丢失了焦点(如调用clearFocus())而其中一个图形项获得焦点那场景会保存这个图形项的焦点信息。

图形项默认无法接收悬停事件,可以使用QGraphicsItem的setAcceptHoverEvents()函数使图形项可以接收悬停事件。

二、运行图

(1)五个图形项的运行图如下图所示。

三、详解

1、QGraphicsScene

  1. #ifndef MYSCENE_H
  2. #define MYSCENE_H
  3. #include <QGraphicsScene>
  4. #include <QGraphicsSceneMouseEvent>
  5. #include <QPaintEvent>
  6. #include <QKeyEvent>
  7. class MyScene : public QGraphicsScene
  8. {
  9. Q_OBJECT
  10. public:
  11. explicit MyScene(QObject *parent = 0);
  12. protected:
  13. void keyPressEvent(QKeyEvent *event);
  14. void mousePressEvent(QGraphicsSceneMouseEvent *event);
  15. signals:
  16. public slots:
  17. };
  18. #endif // MYSCENE_H
  1. #include "myscene.h"
  2. MyScene::MyScene(QObject *parent) :
  3. QGraphicsScene(parent)
  4. {
  5. clearFocus();
  6. }
  7. void MyScene::keyPressEvent(QKeyEvent *event)
  8. {
  9. qDebug("*********MyScene::keyPressEvent***************");
  10. return QGraphicsScene::keyPressEvent(event);
  11. }
  12. void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
  13. {
  14. qDebug("*********MyScene::mousePressEvent***************");
  15. QGraphicsScene::mousePressEvent(event);
  16. }

2、QGraphicsView

  1. #ifndef MYVIEW_H
  2. #define MYVIEW_H
  3. #include <QGraphicsView>
  4. class MyView : public QGraphicsView
  5. {
  6. Q_OBJECT
  7. public:
  8. explicit MyView(QWidget *parent = 0);
  9. protected:
  10. void keyPressEvent(QKeyEvent *event);
  11. void mousePressEvent(QMouseEvent *event);
  12. void paintEvent(QPaintEvent * event);
  13. void mouseMoveEvent(QMouseEvent *event);
  14. signals:
  15. public slots:
  16. };
  17. #endif // MYVIEW_H
  1. #include "myview.h"
  2. #include <QKeyEvent>
  3. MyView::MyView(QWidget *parent) :
  4. QGraphicsView(parent)
  5. {
  6. }
  7. void MyView::keyPressEvent(QKeyEvent *event)
  8. {
  9. qDebug("*********MyView::keyPressEvent***************");
  10. switch (event->key())
  11. {
  12. case Qt::Key_Left :
  13. scale(1.2, 1.2);
  14. break;
  15. case Qt::Key_Right :
  16. scale(1 / 1.2, 1 / 1.2);
  17. break;
  18. case Qt::Key_Up :
  19. rotate(30);
  20. break;
  21. }
  22. QGraphicsView::keyPressEvent(event);
  23. }
  24. void MyView::mousePressEvent(QMouseEvent *event)
  25. {
  26. qDebug("************MyView::mousePressEvent*****************");
  27. QGraphicsView::mousePressEvent(event);
  28. }
  29. void MyView::paintEvent(QPaintEvent *event)
  30. {
  31. qDebug("************MyView::paintEvent*****************");
  32. QGraphicsView::paintEvent(event);
  33. }
  34. void MyView::mouseMoveEvent(QMouseEvent *event)
  35. {
  36. //qDebug("************MyView::mouseMoveEvent*****************");
  37. QGraphicsView::mouseMoveEvent(event);
  38. }

3、QGraphicsItem

  1. #ifndef MYITEM_H
  2. #define MYITEM_H
  3. #include <QGraphicsItem>
  4. #include <QGraphicsSceneEvent>
  5. class MyItem : public QGraphicsItem
  6. {
  7. public:
  8. MyItem();
  9. QRectF boundingRect() const;
  10. void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
  11. QWidget *widget);
  12. void setColor(const QColor &color) { brushColor = color; }
  13. protected:
  14. void keyPressEvent(QKeyEvent *event);
  15. void mousePressEvent(QGraphicsSceneMouseEvent *event);
  16. void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
  17. void hoverLeaveEvent (QGraphicsSceneHoverEvent * event);
  18. void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
  19. void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
  20. private:
  21. QColor brushColor;
  22. };
  23. #endif // MYITEM_H
  1. #include "myitem.h"
  2. #include <QPainter>
  3. #include <QCursor>
  4. #include <QKeyEvent>
  5. #include <QGraphicsSceneHoverEvent>
  6. #include <QGraphicsSceneContextMenuEvent>
  7. #include <QMenu>
  8. MyItem::MyItem()
  9. {
  10. brushColor = Qt::red;
  11. setFlag(QGraphicsItem::ItemIsFocusable);
  12. setFlag(QGraphicsItem::ItemIsMovable);
  13. //setAcceptHoverEvents(true);
  14. }
  15. QRectF MyItem::boundingRect() const
  16. {
  17. qreal adjust = 0.5;
  18. return QRectF(-10 - adjust, -10 - adjust,
  19. 20 + adjust, 20 + adjust);
  20. }
  21. void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
  22. QWidget *widget)
  23. {   qDebug("************MyItem::paint*****************");
  24. if(hasFocus()) {
  25. painter->setPen(QPen(QColor(255,255,255,200)));
  26. } else {
  27. painter->setPen(QPen(QColor(100,100,100,100)));
  28. }
  29. painter->setBrush(brushColor);
  30. painter->drawRect(-10, -10, 20, 20);
  31. }
  32. // 鼠标按下事件处理函数,设置被点击的图形项获得焦点,并改变光标外观
  33. void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
  34. {
  35. qDebug("************MyItem::mousePressEvent*****************");
  36. setFocus();
  37. setCursor(Qt::ClosedHandCursor);
  38. }
  39. // 键盘按下事件处理函数,判断是否是向下方向键,如果是,则向下移动图形项
  40. void MyItem::keyPressEvent(QKeyEvent *event)
  41. {
  42. qDebug("************MyItem::keyPressEvent*****************");
  43. if(event->key() == Qt::Key_Down)
  44. moveBy(0, 10);
  45. }
  46. // 悬停事件处理函数,设置光标外观和提示
  47. void MyItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
  48. {
  49. qDebug("************MyItem::hoverEnterEvent*****************");
  50. setCursor(Qt::OpenHandCursor);
  51. setToolTip("I am item");
  52. }
  53. void MyItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
  54. {
  55. qDebug("************MyItem::hoverLeaveEvent*****************");
  56. setCursor(Qt::ArrowCursor);
  57. }
  58. // 右键菜单事件处理函数,为图形项添加一个右键菜单
  59. void MyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
  60. {
  61. QMenu menu;
  62. QAction *moveAction = menu.addAction("move back");
  63. QAction *actAction = menu.addAction("test");
  64. QAction *selectedAction = menu.exec(event->screenPos());
  65. if(selectedAction == moveAction) {
  66. setPos(0, 0);
  67. }
  68. }
  69. void MyItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
  70. {
  71. qDebug("************MyItem::mouseMoveEvent*****************");
  72. QGraphicsItem::mouseMoveEvent(event);
  73. }

4、main及运行

  1. #include <QApplication>
  2. #include "myitem.h"
  3. #include "myview.h"
  4. #include "myscene.h"
  5. #include <QTime>
  6. int main(int argc,char* argv[ ])
  7. {
  8. QApplication app(argc,argv);
  9. qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
  10. MyScene scene;
  11. scene.setSceneRect(-200, -150, 400, 300);
  12. for(int i = 0; i < 5; ++i) {
  13. MyItem *item = new MyItem;
  14. item->setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
  15. item->setPos(i * 50 - 90, -50);
  16. scene.addItem(item);
  17. }
  18. MyView view;
  19. view.setScene(&scene);
  20. view.setBackgroundBrush(QPixmap(":/background.png"));
  21. view.show();
  22. return app.exec();
  23. }


分析: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框架事件处理(有源码下载)的更多相关文章

  1. Qt浅谈之四十九俄罗斯方块(代码来自网络)

    一.简介 从网上下载了一个Qt实现的俄罗斯方块单机版的源码,觉得非常有意思,故以博客形式记录下来,以便慢慢来研究.在centos6.6下编译运行(注意程序运行需要读取pro目录的配置文件,若把编译目录 ...

  2. Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口

    一.简介 最近看到一篇Qt实现伸缩滑动的窗口的文章,但其代码不完整.便在此重新书写了完整的代码,并开源出来.窗口的中央有滑动条可以动态改变子窗口的大小,隐藏的按钮可以快速伸缩子窗口.其效果图如下: 二 ...

  3. Qt浅谈之三十九圆形进度条(已经有50篇了)

    http://blog.csdn.net/taiyang1987912/article/category/2314763

  4. Qt浅谈内存泄露(总结)

    Qt浅谈内存泄露(总结) 来源 http://blog.csdn.net/taiyang1987912/article/details/29271549 一.简介 Qt内存管理机制:Qt 在内部能够维 ...

  5. Qt浅谈之总结(整理)

    Qt浅谈之总结(整理) 来源 http://blog.csdn.net/taiyang1987912/article/details/32713781 一.简介 QT的一些知识点总结,方便以后查阅. ...

  6. 浅谈Python Web的五大框架

    说到Web Framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界.各种micro-framework.framework不可胜数. 尽管还有一大脚本语言PHP也有 ...

  7. Qt浅谈之二十App自动重启及关闭子窗口

    一.简介 最近因项目需求,Qt程序一旦检测到错误,要重新启动,自己是每次关闭主窗口的所有子窗口但有些模态框会出现问题,因此从网上总结了一些知识点,以备以后的应用. 二.详解 1.Qt结构 int ma ...

  8. Qt浅谈之二十App自动重启及关闭子窗口(六种方法)

    一.简介 最近因项目需求,Qt程序一旦检测到错误,要重新启动,自己是每次关闭主窗口的所有子窗口但有些模态框会出现问题,因此从网上总结了一些知识点,以备以后的应用. 二.详解 1.Qt结构 int ma ...

  9. Qt浅谈之二十六图片滑动效果

    一.简介 博客中发现有作者写的仿360的代码,觉得其中图片滑动的效果很有意思,特提取其中的代码.并加上类似mac的画面移动的动画效果. 二.详解 1.代码一:界面滑动(QWidget) (1)slid ...

随机推荐

  1. Angular7环境搭建报错

    昨天写的2019年Angular7——安装搭建路由方法不太正统,今天又去翻了下angular官网,跟着上面的环境搭建与部署走了一遍 从安装@angular/cli命令行工具开始 本篇主要记录下搭建过程 ...

  2. [RxJS] ReplaySubject with buffer

    A BehaviorSubject can remember the latest value emitted, but what if we wanted Observer B to see all ...

  3. 【t041】距离之和

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 在一条数轴上有N头牛在不同的位置上,每头牛都计算到其它各头牛的距离.求这n*(n-1)个距离的总和. ...

  4. java连接MongoDB查询导出为excel表格

    背景 因为项目需求.每一个星期须要统计每一个公众号7天的訪问数,月底就须要统计一个月的訪问数,40多个公众号.每次手动统计都须要花费1个小时,总之是一项无技术耗时耗神的手工活. 于是.想写个程序来统计 ...

  5. http://lists.mysql.com/mysql

    http://lists.mysql.com/mysql http://www.ehowstuff.com/how-to-fix-mysql-database-error-cant-create-da ...

  6. ArcEngine创建IElement简单例子

    转自IT-GIS终结者原文ArcEngine创建IElement简单例子 代码下载地址:http://files.cnblogs.com/ogis/MapControlApplication2.rar ...

  7. POJ1659Frogs&#39; Neighborhood(lavel定理)

    Frogs' Neighborhood Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 7260   Accepted: 31 ...

  8. sql for xml 还有一种写法(採用 tag 与 union all,简洁易懂)

    sql for xml 还有一种写法(採用 tag 与 union all,简洁易懂) 測试环境:sql 08, 08 R2, 2010,  2012, 2014 等 declare @agent t ...

  9. Android JNI--基础篇(二)

    编写一个可以与C代码交互的android工程需要如下步骤: 1.JAVA代码中写声明native 方法 2. 创建jni目录,编写c代码,方法名字要对应 3.编写Android.mk文件(交叉编译的规 ...

  10. 【u031】租用游艇

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 长江游艇俱乐部在长江上设置了n 个游艇出租站1,2,-,n.游客可在这些游艇出租站租用游艇,并在下游的 ...