QT QGraphicsItem 图元覆盖导致鼠标点击事件不能传递到被覆盖图元

一、概述

在日常开发中,遇到这样一个问题,线图元和引脚图元重叠,导致点击引脚图元,没有进入引脚图元的鼠标点击事件中。

二、产生原因

如果您的 QGraphicsItem 上有一个图元覆盖了它,可能会导致鼠标事件无法正常触发。这是因为在 QGraphicsScene 中,当多个图元重叠时,只有位于顶部的图元才能接收鼠标事件。 

三、解决办法

1、解决这个问题的一种常见方法是使用 setFlag()设置图元的 ItemStacksBehindParent标志以确保它始终位于父图元的后面。这样可以确保它可以接收鼠标事件而不会被其他图元遮挡。

ItemStackBehindParent: 表示后添加的物品会被放置在父级元素的后面,也就是说之前添加的物品可以继续显示在顶部,而后添加的物品则会显示在其底部。

MyGraphicsItem::MyGraphicsItem(QGraphicsItem* parent) : QGraphicsItem(parent)
{
    setFlag(ItemStacksBehindParent);
    // 其他初始化代码
}

2、另一种方法是调整覆盖图元的z值,确保目标图元位于覆盖图元的上方。您可以使用 setZValue() 方法设置图元的z值。 Z值大的在上方。

// 创建一个矩形图元
QGraphicsRectItem* rectItem = new QGraphicsRectItem(0, 0, 50, 50);
rectItem->setFlag(QGraphicsItem::ItemIsSelectable);  // 添加选择标记
rectItem->setZValue(1);  // 将该图元置于上层

// 创建一个椭圆图元
QGraphicsEllipseItem* ellipseItem = new QGraphicsEllipseItem(0, 0, 50, 50);
ellipseItem->setFlag(QGraphicsItem::ItemIsSelectable);  // 添加选择标记
ellipseItem->setZValue(0);  // 将该图元置于下层

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要支持键盘输入焦点和按键事件,QGraphicsItem需要继承自QGraphicsItem类,并且重写下列方法: 1. void keyPressEvent(QKeyEvent *event):重写keyPressEvent方法处理按键事件; 2. QVariant itemChange(GraphicsItemChange change, const QVariant &value):重写itemChange方法处理焦点事件。 在重写keyPressEvent方法时,需要注意: 1. QGraphicsItem没有默认的键盘焦点,因此需要使用setFlag()方法将QGraphicsItemItemIsFocusable标志设置为true,才能接收键盘事件; 2. 在keyPressEvent方法中,需要通过QKeyEvent的key()方法获取按下的键,并根据需要进行处理。 在重写itemChange方法时,需要注意: 1. 当焦点状态改变时,会触发GraphicsItemChange类型的change参数为QGraphicsItem::ItemFocusHasChanged的信号,可以在itemChange方法中重写处理该信号; 2. 在itemChange方法中,可以通过value参数获取焦点状态的改变,并根据需要进行处理。 举例来说,以下代码是QGraphicsItem的一个子类,在该类中实现了键盘输入焦点和按键事件的支持: ```c++ class MyItem : public QGraphicsItem { public: MyItem(QGraphicsItem *parent = nullptr) : QGraphicsItem(parent) { setFlag(ItemIsFocusable, true); } QRectF boundingRect() const override { return QRectF(0, 0, 100, 100); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override { painter->drawRect(boundingRect()); } void keyPressEvent(QKeyEvent *event) override { switch (event->key()) { case Qt::Key_Up: setPos(pos() + QPointF(0, -10)); break; case Qt::Key_Down: setPos(pos() + QPointF(0, 10)); break; case Qt::Key_Left: setPos(pos() + QPointF(-10, 0)); break; case Qt::Key_Right: setPos(pos() + QPointF(10, 0)); break; default: break; } } QVariant itemChange(GraphicsItemChange change, const QVariant &value) override { if (change == QGraphicsItem::ItemFocusHasChanged) { if (value.toBool()) { qDebug() << "Item has gained focus!"; } else { qDebug() << "Item has lost focus!"; } } return QGraphicsItem::itemChange(change, value); } }; ``` 在上述代码中,MyItem类重写了QGraphicsItem的keyPressEvent和itemChange方法,实现了键盘输入焦点和按键事件的支持。具体地,该类在构造函数中将ItemIsFocusable标志设置为true,使其能够接受键盘焦点;在keyPressEvent方法中,根据按下的键进行移动;在itemChange方法中,处理焦点状态的改变。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值