Qt开发高级进阶:QGraphicsXxxxItem等无法收到鼠标事件的原因

本文探讨了QGraphicsItems在Qt中处理鼠标事件时遇到的问题,包括为何mouseMoveEvent无法接收到消息的情况,以及如何避免错误代码导致的事件丢失。主要集中在Qt的事件传递机制和父子项之间的消息交互。同时提到了item未正确初始化或禁用状态可能导致事件无法正常接收。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

QGraphicsItems收不到消息分有好几种情况。除了错误的代码外,还有一些对Qt原理理解上的问题(Qt埋下的坑)。

情况 (1)如果是mouseMoveEvent收不到消息,而mousePressEvent能收到消息,则往往在mousePressEvent中不能把消息传递给父类。例如

void QGraphicsEllipseSubItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
    qDebug() << "ellipse press event";
    
    event->accept();
    // NOTE: press -> Move -> Release -> Context Menu Event.
    //       You have to comment out this for preventing message passing to parent
    //       otherwise the mouseMoveEvent will not be called!
    //QGraphicsEllipseItem::mousePressEvent(event);
}

在这时里,如果QGraphicsEllipseItem::mousePressEvent(event);这一句不注释掉,那么mouseMoveEvent就收不到消息。原因是这些控件会把消息传回给父类。Qt官方有一大段解释,如下,

void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
This event handler, for event event, can be reimplemented to receive mouse press events
 for this item. Mouse press events are only delivered to items that accept the mouse 
button that is pressed. By default, an item accepts all mouse buttons, but you can 
change this by calling setAcceptedMouseButtons().
The mouse press event decides which item should become the mouse grabber (see 
QGraphicsScene::mouseGrabberItem()). If you do not reimplement this function, the press
event will propagate to any topmost item beneath this item, and no other mouse events
will be delivered to this item.
If you do reimplement this function, event will by default be accepted (see 
QEvent::accept()), and this item is then the mouse grabber. This allows the item to
receive future move, release and doubleclick events. If you call QEvent::ignore()
on event, this item will lose the mouse grab, and event will propagate to any 
topmost item beneath. No further mouse events will be delivered to this item 
unless a new mouse press event is received.
The default implementation handles basic item interaction, such as selection 
and moving. If you want to keep the base implementation when reimplementing
 this function, call QGraphicsItem::mousePressEvent() in your reimplementation.
The event is QEvent::ignore()d for items that are neither movable nor selectable.
See also mouseMoveEvent(), mouseReleaseEvent(), mouseDoubleClickEvent(), and sceneEvent().

情况(2)错误的代码,比如有些item在加入到scene中去之前没有初始化。比如QGraphicsPixmapItem中没有图片,或者item的setEanble或某个其他的原因,使这个item的enabled状态为false。

本文结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值