一、简介

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

最新文章

  1. Ubuntu14.04通过pyenv配置多python
  2. php验证是否是md5编码的代码
  3. zend studio 10破解/汉化(转发)
  4. 安卓Handler机制的例子
  5. [九度OJ]1137.浮点数加法
  6. jquery中的 .html(),.val().text()
  7. fedora23开发环境搭建手册
  8. 《asp.net mvc3 高级编程》第四章 模型
  9. js验证日期
  10. 一张地图告诉你,只JavaScript不够!
  11. Angularjs -- 核心概念
  12. 在asp.net webservice中如何使用session
  13. 用canvas实现红心飘飘的动画效果
  14. awk+sed编程
  15. SQL格式化插件—SQL Pretty Printer
  16. 洛谷P3455 ZAP-Queries [POI2007] 莫比乌斯反演+数论分块
  17. 【Shell】获取当前路径
  18. android:碎片的生命周期
  19. shell执行字符串中的命令
  20. TensorFlow安装,升级,基本操作

热门文章

  1. 从零开始使用git第二篇:git的日常操作
  2. vue项目中一些文件的作用
  3. 8、linux下输入子系统
  4. 通过WPF中UserControl内的按钮点击关闭父窗体
  5. AndroidAnnotations使用说明书—AndroidAnnotations是怎样工作的?
  6. Swift 中异常抛出和四种异常处理
  7. null与对象的复杂关系(typeof null的结果是object的原因)
  8. 【35.37%】【codeforces 556C】Case of Matryoshkas
  9. hdu 1166 敌兵布阵 线段树 点更新
  10. Java高级个人笔记(RandomStringUtils工具类)