QT绘图高级技术(一)GraphicsView框架事件处理
[+]
一、简介GraphicsView支持事件传播体系结构,可以使图元在场景scene中得到提高了已被的精确交互能力。图形视图框架中的事件都是首先由视图进行接收,然后传递给场景,再由场景给相应的图形项。
对于键盘鼠标事件,scene会传递给获得焦点的图形项。如果场景没有获得焦点,那键盘事件会丢弃;如果调用场景setFocus()或者场景中的一个图形项获得了焦点,那么场景会自动获得焦点;如果场景丢失了焦点(如调用clearFocus())而其中一个图形项获得焦点那场景会保存这个图形项的焦点信息。
图形项默认无法接收悬停事件,可以使用QGraphicsItem的setAcceptHoverEvents()函数使图形项可以接收悬停事件。
(1)五个图形项的运行图如下图所示。
[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);
}
[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)
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。