Important: Please read the Qt Code of Conduct -

How Does A Graphics Item Know When The Mouse Is "Over" It?

  • As the documentation says in regards to setCursor(), "The mouse cursor will assume this shape when it's over this item".

    In my scene implementation I am debugging with something like:

    void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent)
    QPointF pt = mouseEvent->scenePos();
    QPointF mpt = my_item->mapFromScene(pt);
    QRectF bb = my_item->boundingRect();
    QPainterPath shape = my_item->shape();
    qDebug() << "pt=" << pt
    << "mpt=" << mpt
    << "bb contains=" << bb->contains(mpt)
    << "shape contains=" << shape.contains(mpt)
    << "myitem contains=" << my_item->contains(mpt)
    << "items=" << items(pt,Qt::IntersectsItemShape,

    QGraphicsScene::mouseMoveEvent( mouseEvent);


    When I move the mouse over my_item, I get:

    • bb contains mpt
    • my_item contains mpt
    • my_item's shape contains mpt

    However, for the size of items I get zero :(

    • No hover event on my item occurs
    • setCursor() doesn't work

    Other Hints:

    • I think it has to do with my_item->setParentItem(0) maybe.
    • Sometimes I do get the hover event on my_item... i just don't see any rhyme or reason to it

  • Cannot see anything wrong in the code above (except that it should be bb.contains(mpt), but that's just a typo I assume). You might want to test what itemAt() returns as well, because that is probably the function used internally to set the cursor. (Or, you could have a look in the source code to see exactly how it determines which cursor to use.)
    Regarding hover events, I assume you have called setAcceptHoverEvents(true).

  • You need to call

    QGraphicsItem::setAcceptsHoverEvents( true );

    on your items. For performance reasons items do not accept hover events by default.

  • Thanks for the replies.

    I did set setAcceptHoverEvents(true).

    And yes, that was a typo.
    And yes, the items() or itemAt() is how I realized that the internal function is not doing the contains() for shape as I assumed it might.

    I wish I knew what the items()/itemAt() was doing internally. Suppose I can get the source for it... but afraid it'd take me forever to wade through it.

    Honestly, I think I've inadvertently done something else and this must be some side effect. Oh, the pain.

  • I read also, in regards to itemAt() that "This function is deprecated and returns incorrect results if the scene contains items that ignore transformations."

    My scene has no items that I've explicitly set to ignore transforms.

  • Can you provide a small compilable example that reproduces the problem please?

  • I am going to try upgrading to the latest Qt 4.7.3. If this doesn't work, I may try to come up with an example. The thing is, for the most part it all works. When I do the following it stops working:

    Also, it's not that it is completely broken, sometimes I do get the hover event over my_item. It's like I have inadvertently done something to the scene that is causing the internal algorithm to fail.

    If I could live with my_item not being a top level item it'd be okay... but really the fact that it's not working like I expect tells me I am missing something important.

    Thanks again for the response. Just knowing somebody is there helps. I was at my wits end on this problem.

  • OK good luck!

  • Well, the upgrade to 4.7.3 didn't work.

    However, I was able to "fix" it. I told the scene to use the linear indexing scheme and it worked. I am guessing I need to do some sort of refresh on the bsp indexer when I reparent my_item as a toplevel item. Anyhow, here's the "fix":


  • I ran into this problem again. I wish I knew what I was doing wrong. I am using events to cause graphic item position changes. It's like the scene's BspTreeIndex needs to refresh it's cache. I am guessing that Qt assumes an order and I am violating it. Anyhow, I will drop back to QGraphicsScene::NoIndex. Hopefully I won't get too much of a performance penalty.

Log in to reply