Search code examples
c++qtqgraphicsviewqgraphicsitemqcursor

Change the cursor if you pass to a QGraphicsRectItem Qt c++


I would like to change the cursor if I go over a rectangle like QGraphicsRectItem.

I have a class that inherits from QGraphicsView and the rectangles are displayed in a QGraphicScene.

I implemented mouse events with eventFilter.

The problem is that the cursor changes when I have already clicked on the rectangle whereas I would like it to change when I pass on it. I already made the cursor change with a QAbstractButton, but the QGraphicsRectItem::enterEvent(event) does not work.

Here is my code with QAbstractButton :

void ToggleButton::enterEvent(QEvent *event) {
    setCursor(Qt::PointingHandCursor);
    QAbstractButton::enterEvent(event);
}

In this case it works.

And here is my code to detect if I pass on a rectangle:

DetecRect::DetecRect(QWidget* parent) : 
    QGraphicsView(parent)
{
     scene = new QGraphicsScene(this);
     pixmapItem=new QGraphicsPixmapItem(pixmap);
     scene->addItem(pixmapItem);
     this->setScene(scene);
     this->setMouseTracking(true);
     scene->installEventFilter(this);
}

bool DetecRect::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == scene){
        // press event
        QGraphicsSceneMouseEvent *mouseSceneEvent;
        if(event->type() == QEvent::GraphicsSceneMousePress){
            mouseSceneEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
            if(mouseSceneEvent->button() & Qt::LeftButton){

            }
        // move event
        } else if (event->type() == QEvent::GraphicsSceneMouseMove) {
            mouseSceneEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
             //selectedItem is a QGraphicsItem
            if(this->selectedItem && this->selectedItem->type() == QGraphicsRectItem::Type){
                selectedItem->setCursor(Qt::PointingHandCursor);
            }
        }
        // release event
        else if (event->type() == QEvent::GraphicsSceneMouseRelease) {
            mouseSceneEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
        }
    }
    return QGraphicsView::eventFilter(watched, event);
}

In this code, the cursor changes if I clicked on it once. But do not change if I pass directly on it. Why?


Solution

  • You do not have to implement the hoverEnterEvent method or hoverLeaveEvent, you just have to set a cursor to the item as shown below:

    #include <QApplication>
    #include <QGraphicsRectItem>
    #include <QGraphicsView>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QGraphicsView view;
        QGraphicsScene *scene = new QGraphicsScene(&view);
        view.setScene(scene);
    
        QGraphicsRectItem *rit = scene->addRect(QRectF(-50, -50, 100, 100), QPen(Qt::black), QBrush(Qt::gray));
        rit->setCursor(Qt::CrossCursor);
    
        QGraphicsRectItem *rit2 = new QGraphicsRectItem(QRectF(-50, -50, 100, 100));
        rit2->setPen(QPen(Qt::white));
        rit2->setBrush(QBrush(Qt::green));
        rit2->setCursor(Qt::PointingHandCursor);
        rit2->setPos(200, 100);
        scene->addItem(rit2);
    
        view.resize(640, 480);
        view.show();
        return a.exec();
    }