[+]

一、简介

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

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

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

二、运行图

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


三、详解1、QGraphicsScene


[cpp]view plaincopy

#ifndefMYSCENE_H

#defineMYSCENE_H

#include<QGraphicsScene>

#include<QGraphicsSceneMouseEvent>

#include<QPaintEvent>

#include<QKeyEvent>

classMyScene:publicQGraphicsScene

{

Q_OBJECT

public:

explicitMyScene(QObject*parent=0);

protected:

voidkeyPressEvent(QKeyEvent*event);

voidmousePressEvent(QGraphicsSceneMouseEvent*event);

signals:

publicslots:

};

#endif//MYSCENE_H

[cpp]view plaincopy

#include"myscene.h"

MyScene::MyScene(QObject*parent):

QGraphicsScene(parent)

{

clearFocus();

}

voidMyScene::keyPressEvent(QKeyEvent*event)

{

qDebug("*********MyScene::keyPressEvent***************");

returnQGraphicsScene::keyPressEvent(event);

}

voidMyScene::mousePressEvent(QGraphicsSceneMouseEvent*event)

{

qDebug("*********MyScene::mousePressEvent***************");

QGraphicsScene::mousePressEvent(event);

}


2、QGraphicsView

[cpp]view plaincopy

#ifndefMYVIEW_H

#defineMYVIEW_H

#include<QGraphicsView>

classMyView:publicQGraphicsView

{

Q_OBJECT

public:

explicitMyView(QWidget*parent=0);

protected:

voidkeyPressEvent(QKeyEvent*event);

voidmousePressEvent(QMouseEvent*event);

voidpaintEvent(QPaintEvent*event);

voidmouseMoveEvent(QMouseEvent*event);

signals:

publicslots:

};

#endif//MYVIEW_H

[cpp]view plaincopy

#include"myview.h"

#include<QKeyEvent>

MyView::MyView(QWidget*parent):

QGraphicsView(parent)

{

}

voidMyView::keyPressEvent(QKeyEvent*event)

{

qDebug("*********MyView::keyPressEvent***************");

switch(event->key())

{

caseQt::Key_Left:

scale(1.2,1.2);

break;

caseQt::Key_Right:

scale(1/1.2,1/1.2);

break;

caseQt::Key_Up:

rotate(30);

break;

}

QGraphicsView::keyPressEvent(event);

}

voidMyView::mousePressEvent(QMouseEvent*event)

{

qDebug("************MyView::mousePressEvent*****************");

QGraphicsView::mousePressEvent(event);

}

voidMyView::paintEvent(QPaintEvent*event)

{

qDebug("************MyView::paintEvent*****************");

QGraphicsView::paintEvent(event);

}

voidMyView::mouseMoveEvent(QMouseEvent*event)

{

//qDebug("************MyView::mouseMoveEvent*****************");

QGraphicsView::mouseMoveEvent(event);

}

3、QGraphicsItem

[cpp]view plaincopy

#ifndefMYITEM_H

#defineMYITEM_H

#include<QGraphicsItem>

#include<QGraphicsSceneEvent>

classMyItem:publicQGraphicsItem

{

public:

MyItem();

QRectFboundingRect()const;

voidpaint(QPainter*painter,constQStyleOptionGraphicsItem*option,

QWidget*widget);

voidsetColor(constQColor&color){brushColor=color;}

protected:

voidkeyPressEvent(QKeyEvent*event);

voidmousePressEvent(QGraphicsSceneMouseEvent*event);

voidhoverEnterEvent(QGraphicsSceneHoverEvent*event);

voidhoverLeaveEvent(QGraphicsSceneHoverEvent*event);

voidcontextMenuEvent(QGraphicsSceneContextMenuEvent*event);

voidmouseMoveEvent(QGraphicsSceneMouseEvent*event);

private:

QColorbrushColor;

};

#endif//MYITEM_H

[cpp]view plaincopy

#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);

}

QRectFMyItem::boundingRect()const

{

qrealadjust=0.5;

returnQRectF(-10-adjust,-10-adjust,

20+adjust,20+adjust);

}

voidMyItem::paint(QPainter*painter,constQStyleOptionGraphicsItem*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);

}

//鼠标按下事件处理函数,设置被点击的图形项获得焦点,并改变光标外观

voidMyItem::mousePressEvent(QGraphicsSceneMouseEvent*event)

{

qDebug("************MyItem::mousePressEvent*****************");

setFocus();

setCursor(Qt::ClosedHandCursor);

}

//键盘按下事件处理函数,判断是否是向下方向键,如果是,则向下移动图形项

voidMyItem::keyPressEvent(QKeyEvent*event)

{

qDebug("************MyItem::keyPressEvent*****************");

if(event->key()==Qt::Key_Down)

moveBy(0,10);

}

//悬停事件处理函数,设置光标外观和提示

voidMyItem::hoverEnterEvent(QGraphicsSceneHoverEvent*event)

{

qDebug("************MyItem::hoverEnterEvent*****************");

setCursor(Qt::OpenHandCursor);

setToolTip("Iamitem");

}

voidMyItem::hoverLeaveEvent(QGraphicsSceneHoverEvent*event)

{

qDebug("************MyItem::hoverLeaveEvent*****************");

setCursor(Qt::ArrowCursor);

}

//右键菜单事件处理函数,为图形项添加一个右键菜单

voidMyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent*event)

{

QMenumenu;

QAction*moveAction=menu.addAction("moveback");

QAction*actAction=menu.addAction("test");

QAction*selectedAction=menu.exec(event->screenPos());

if(selectedAction==moveAction){

setPos(0,0);

}

}

voidMyItem::mouseMoveEvent(QGraphicsSceneMouseEvent*event)

{

qDebug("************MyItem::mouseMoveEvent*****************");

QGraphicsItem::mouseMoveEvent(event);

}

4、main及运行

[cpp]view plaincopy

#include<QApplication>

#include"myitem.h"

#include"myview.h"

#include"myscene.h"

#include<QTime>

intmain(intargc,char*argv[])

{

QApplicationapp(argc,argv);

qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

MyScenescene;

scene.setSceneRect(-200,-150,400,300);

for(inti=0;i<5;++i){

MyItem*item=newMyItem;

item->setColor(QColor(qrand()%256,qrand()%256,qrand()%256));

item->setPos(i*50-90,-50);

scene.addItem(item);

}

MyViewview;

view.setScene(&scene);

view.setBackgroundBrush(QPixmap(":/background.png"));

view.show();

returnapp.exec();

}


分析:keyPressEvent键盘按下事件由View—Scene—Item



分析:mousePressEven鼠标按下事件由View—Scene—Item

分析:事件项Item没有获得焦点时,mousePressEven鼠标按下事件只由View传递到Scene。

分析:事件项Item的悬停事件,在构造函数中设置了setAcceptHoverEvents(true)