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 ...
随机推荐
- POJ 1270 Following Orders 拓扑排序
http://poj.org/problem?id=1270 题目大意: 给你一串序列,然后再给你他们部分的大小,要求你输出他们从小到大的所有排列. 如a b f g 然后 a<b ,b< ...
- 怎样在一个fragment or 随意类中操作还有一个fragment中的方法
1 怎样在acitivty中运行fragment中的方法: 首先获得这个Fragment的对象 xxxFragment fragmentObject = (xxxFragment) getFragme ...
- WindowImplBase::OnSysCommand-------duilib在最大化和还原间切换
virtual LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if( wPar ...
- ZYNQ7000 LVDS接口输出配置
xilinx 7系列芯片不再支持LVDS33电平,在VCCO电压为3.3V的情况下无法使用LVDS25接口. 有些设计者想通过在软件中配置为LVDS25,实际供电3.3V来实现LVDS33也是无效的, ...
- 字典(dictionary)的设计
1. 简单接口 struct Dict{ bool has(const string& key); void insert(const string& key, const strin ...
- Ubuntu12.04LTS SDK无法更新
1.打开终端输入sudo gedit /etc/hosts 加入下面 2.加入下列文字到文件里: 203.208.46.146 dl.google.com 203.208.46 ...
- 超级牛X的免费开源小工具之tldr
github介绍:http://tldr-pages.github.io/ github源码:https://github.com/tldr-pages/tldr 什么是tldr? 新命令行世界?还是 ...
- JavaScript 初学者应知的 24 条最佳实践
原文:24 JavaScript Best Practices for Beginners (注:阅读原文的时候没有注意发布日期,觉得不错就翻译了,翻译到 JSON.parse 那一节觉得有点不对路才 ...
- xv6进程切换-swtch函数
https://blog.csdn.net/Swartz2015/article/details/61615603 xv6进程切换-swtch函数 进程切换中由于需要保存当前进程的寄存器状态信息,又要 ...
- ios开发瀑布流框架的应用
一:瀑布流框架的应用:将封装好的瀑布流框架导入,遵守协议 二:代码: #import "HMShopsViewController.h" #import "HMShopC ...