You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt自定义QGraphicsPolygonItem的mousePressEvent不生效问题

问题核心诱因
  • 你继承QGraphicsPolygonItem后,仅在自定义成员变量pol1中存储了箭头的多边形点位,没有调用基类的setPolygon()方法将形状同步给基类。Qt图形视图框架的鼠标命中检测完全依赖图元自身上报的boundingRect()(边界矩形)和shape()(精确形状),QGraphicsPolygonItem默认的这两个返回值都是基于自身内部存储的多边形计算的;未同步形状的情况下,基类会判定该图元是尺寸为0的空对象,鼠标点击时根本不会将该图元纳入命中检测范围,自然不会触发你重写的mousePressEvent。
  • 你当前重写的mousePressEvent没有调用基类的对应实现,就算事件能正常送达,也会打断Qt默认的事件传播链,可能导致后续选中、拖拽等交互逻辑异常。
  • 额外隐患:你重写paint函数时直接绘制自定义成员变量的多边形,没有和基类的形状同步,后续如果修改图元大小、多边形点位,很容易出现绘制内容和命中区域不匹配、渲染残影等问题。
可行解决方案
  1. 构造函数中完成多边形点位定义后,调用setPolygon()将形状同步给基类,让框架能正确计算图元的可点击区域。
  2. 重写的事件处理函数中,执行完自定义逻辑后调用基类的对应事件方法,保证事件传播正常。
  3. (可选)移除冗余的自定义多边形成员变量,直接使用基类提供的polygon()/setPolygon()接口管理形状,避免绘制内容和命中区域不一致。如果不需要高度自定义绘制逻辑,甚至可以直接删除重写的paint函数,通过基类的setBrush()接口设置填充色即可。

修改后代码

tranzicija.h

#include <QObject>
#include <QGraphicsPolygonItem>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>

class tranzicija:public QObject,public QGraphicsPolygonItem
{
    Q_OBJECT
public:
    tranzicija();
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
private:
    // 可选:如果不需要额外操作,可以删掉pol1成员,直接用基类接口管理多边形
    QPolygonF pol1;
    void pomjeriproces();
};

tranzicija.cpp

#include "tranzicija.h"
#include <QDebug>

tranzicija::tranzicija()
{
    pol1 << QPointF(0,45)  << QPointF(60,45) << QPointF(60,35) << QPointF(100, 50)
         << QPointF(60,65) << QPointF(60,55) << QPointF(0,55)  << QPointF(0,45);
    // 核心修复:将多边形同步给基类,用于命中检测和边界计算
    setPolygon(pol1);
    // 如果不需要自定义paint,直接设置画刷即可,无需重写paint
    // setBrush(Qt::green);
}

void tranzicija::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << "The button was pressed!";
    // 调用基类实现,保证事件传播正常
    QGraphicsPolygonItem::mousePressEvent(event);
}

void tranzicija::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);
    QBrush brush(Qt::green);
    painter->setBrush(brush);
    painter->setRenderHint(QPainter::Antialiasing);
    // 推荐直接调用基类的polygon()获取形状,避免和设置的命中区域不一致
    painter->drawPolygon(polygon());
}

dialog.cpp(原有逻辑无需修改,可直接生效)

//Poligon start => ready
tranzicija *tr = new tranzicija();
tr->setRotation(45);
tr->setPos(170,125);
tr->setScale(0.8);
scene->addItem(tr);

补充说明:如果后续需要给图元添加选中、拖拽、悬浮等交互效果,只需要通过setFlag()方法开启对应的图元标志即可,例如tr->setFlag(QGraphicsItem::ItemIsSelectable, true);即可开启选中支持。

内容的提问来源于stack exchange,提问作者Don Marquez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 23:09:18