Qt浅谈之十八:GraphicsView框架事件处理

来源:互联网 发布:在上海工作的感受 知乎 编辑:程序博客网 时间:2024/05/19 04:02

一、简介

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

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

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

二、运行图

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


三、详解

1、QGraphicsScene

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

2、QGraphicsView

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

3、QGraphicsItem

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

4、main及运行

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

分析: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

原创粉丝点击