Qt 的图形视图框架(Graphics View Framework)提供了一套丰富的类来管理大量的自定义 2D 图形项(QGraphicsItem),以及这些图形项之间的交互和事件处理。在这个框架中,事件处理是一个关键部分,它允许你响应各种用户输入,如鼠标点击、键盘操作、鼠标移动和悬停等。通过键盘处理的话,需要设置焦点,在QGraphicsScene中使用setFoucesItem()函数可以设置焦点,或者图形项使用setFouce()获取焦点。
一、事件处理机制
在 Qt 的图形视图框架中,事件处理主要通过以下几个关键类进行:
-
QGraphicsScene:负责管理所有图形项(QGraphicsItem)的容器。虽然它本身不直接处理事件,但它会将事件传递给场景中的图形项。
-
QGraphicsItem:是图形项的基类,所有自定义图形项都应该继承自这个类。QGraphicsItem 提供了许多与事件处理相关的虚函数,如
mousePressEvent
、mouseMoveEvent
、mouseReleaseEvent
、hoverEnterEvent
、hoverMoveEvent
和hoverLeaveEvent
等。 -
QGraphicsView:是显示 QGraphicsScene 内容的窗口部件。它负责处理视口(viewport)中的事件,并将这些事件转换为场景中的坐标,然后传递给 QGraphicsScene,再由 QGraphicsScene 将事件传递给适当的 QGraphicsItem。
二、主要事件
1、鼠标事件
item.h
#ifndef ITEM_H
#define ITEM_H
#include<QGraphicsItem>
#include<QGraphicsScene>
#include<QGraphicsView>
#include<QMouseEvent>
class Item : public QGraphicsItem
{
public:
Item();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget );
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) ;//鼠标移动事件
void mousePressEvent(QGraphicsSceneMouseEvent *event) ;//鼠标点击事件
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) ;//鼠标松开事件
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) ;//鼠标双击事件
private:
QColor color;//颜色
};
#endif // ITEM_H
item.cpp
#include "item.h"
Item::Item()
{
color=QColor(Qt::black);//默认为黑色
}
QRectF Item::boundingRect() const
{
qreal penwidget=1;
return QRectF(-penwidget/2,-penwidget/2,100+penwidget,100+penwidget);
}
void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
painter->setBrush(color);
painter->drawRect(0,0,100,100);//画矩形
}
void Item::mouseMoveEvent(QGraphicsSceneMouseEvent *event) //鼠标移动事件
{
color=QColor(Qt::green);
update();
}
void Item::mousePressEvent(QGraphicsSceneMouseEvent *event) //鼠标点击事件
{
setFocus();//设置焦点
color=QColor(Qt::red);
update();
}
void Item::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) //鼠标松开事件
{
color=QColor(Qt::yellow);
update();
}
void Item::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) //鼠标双击事件
{
color=QColor(Qt::blue);
update();
}
2、停靠事件
默认情况下,不会接收悬停事件,需要使用setAcceptHoverEvents()开启接收悬停事件。
#include "item.h"
Item::Item()
{
color=QColor(Qt::black);//默认为黑色
setAcceptHoverEvents(true);//开启接收悬停
}
QRectF Item::boundingRect() const
{
qreal penwidget=1;
return QRectF(-penwidget/2,-penwidget/2,100+penwidget,100+penwidget);
}
void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
painter->setBrush(color);
painter->drawRect(0,0,100,100);//画矩形
}
void Item::hoverMoveEvent(QGraphicsSceneHoverEvent *event) //悬停移动
{
color=QColor(Qt::green);//绿色
update();
}
void Item::hoverEnterEvent(QGraphicsSceneHoverEvent *event) //悬停输入
{
}
void Item::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) //悬停离开
{
color=QColor(Qt::blue);//蓝色
update();
}
3、键盘事件
注意:
- 使用键盘事件的控件需要获取焦点,QGraphicsItem的话使用 setFocus()开启。
- 需要使用setFlag()函数开启标志。
QGraphicsItem::ItemIsMovable | 支持使用鼠标进行交互式移动。通过单击该项目然后拖动,该项目将与鼠标光标一起移动。 |
QGraphicsItem::ItemIsSelectable | 支持选择。启用此功能将启用 setSelected() 来切换项目的选择。 |
QGraphicsItem::ItemIsFocusable | 该项支持键盘输入焦点(即,它是输入项)。启用此标志将允许项目接受焦点 |
QGraphicsItem::ItemClipsToShape | 项目将剪辑到其自己的形状。该项目无法绘制或接收鼠标、平板电脑、拖放或将事件悬停在其形状之外。默认情况下处于禁用状态 |
QGraphicsItem::ItemClipsChildrenToShap | 项目将其所有后代的绘画剪辑成自己的形状。作为此项目的直接或间接子项的项不能在此项的形状之外绘制。 |
QGraphicsItem::ItemIgnoresTransformations | 项目忽略继承的变换,此标志可用于使文本标签项保持水平且不缩放,因此在转换视图时它们仍可读。 |
#include "item.h"
Item::Item()
{
color=QColor(Qt::black);//默认为黑色
setFlag(QGraphicsItem::ItemIsFocusable);//设置标志
}
QRectF Item::boundingRect() const
{
qreal penwidget=1;
return QRectF(-penwidget/2,-penwidget/2,100+penwidget,100+penwidget);
}
void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
painter->setBrush(color);
painter->drawRect(0,0,100,100);//画矩形
}
void Item::keyPressEvent(QKeyEvent *event) //键盘点击
{
if(event->key()==Qt::Key_Up)//向上
{
moveBy(0,-10);
}
else if(event->key()==Qt::Key_Down)//向下
{
moveBy(0,10);
}
else if(event->key()==Qt::Key_Left)//向左
{
moveBy(-10,0);
}
else if(event->key()==Qt::Key_Right)//向右
{
moveBy(10,0);
}
else{
}
}
void Item::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
setFocus();//设置焦点
}
4、拖曳事件
注意:
- 默认不会开启拖拽,需要使用 setAcceptDrops(true)开启
- 想要实现拖动控件的话还要开启 setFlag(QGraphicsItem::ItemIsMovable);
#include "item.h"
Item::Item()
{
color=QColor(Qt::black);//默认为黑色
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);//设置标志
setAcceptDrops(true);//开启拖拽
}
QRectF Item::boundingRect() const
{
qreal penwidget=1;
return QRectF(-penwidget/2,-penwidget/2,100+penwidget,100+penwidget);
}
void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
painter->setBrush(color);
painter->drawRect(0,0,100,100);//画矩形
}
5、上下文菜单事件
contextMenuEvent() | 重新实现此事件处理程序以处理上下文菜单事件 |
#include "item.h"
Item::Item()
{
color=QColor(Qt::black);//默认为黑色
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);//设置标志
setAcceptDrops(true);//开启拖拽
}
QRectF Item::boundingRect() const
{
qreal penwidget=1;
return QRectF(-penwidget/2,-penwidget/2,100+penwidget,100+penwidget);
}
void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
painter->setBrush(color);
painter->drawRect(0,0,100,100);//画矩形
}
void Item::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
QMenu menu;
QAction *red = menu.addAction("red");
QAction *yellow = menu.addAction("yellow");
QAction *green = menu.addAction("green");
QAction *blue = menu.addAction("blue");
QObject::connect(red,&QAction::triggered,[=]()
{
color = Qt::red;
update();
});
QObject::connect(yellow,&QAction::triggered,[=]()
{
color = Qt::yellow;
update();
});
QObject::connect(green,&QAction::triggered,[=]()
{
color = Qt::green;
update();
});
QObject::connect(blue,&QAction::triggered,[=]()
{
color = Qt::blue;
update();
});
menu.exec(event->screenPos());
}
qq群交流:698593923
觉得有帮助的话,打赏一下呗。。