[SOLVED] QGraphicsItem events not working on some item's area



  • Hello,

    I have MyRectangle class which inherits from QGraphicsItem and draws a basic rectangle.

    @
    #include "myrectangle.h"
    #include <QPainter>
    #include <QStyleOptionGraphicsItem>

    MyRectangle::MyRectangle()
    {
    this->setFlag(QGraphicsItem::ItemIsSelectable);
    isPressed = false;
    }

    MyRectangle::~MyRectangle()
    {

    }

    void MyRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
    QPen pen(Qt::white);
    pen.setWidth(2);
    painter->setPen(pen);
    QRectF rec = boundingRect();

    QBrush brush(Qt::red);
    brush.setStyle(Qt::SolidPattern);
    
    /*if(isPressed){
        brush.setColor(Qt::green);
    }*/
    
    if(option->state & QStyle::State_Selected){
        brush.setColor(Qt::blue);
    }
    
    painter->fillRect(rec,brush);
    

    }

    void MyRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
    isPressed = true;
    update();
    }

    QRectF MyRectangle::boundingRect() const
    {
    return QRectF(0,0,60,40);
    }
    @

    In my mainwindow, I just add some of these MyRectangles :

    @
    scene = new QGraphicsScene();
    ui->graphicsView->setScene(scene);
    scene->setSceneRect(0,0,ui->graphicsView->width(),ui->graphicsView->height());
    rec = new MyRectangle;
    rec2 = new MyRectangle;
    rec3 = new MyRectangle;
    rec4 = new MyRectangle;

    scene->addItem(rec);
    scene->addItem(rec2);
    scene->addItem(rec3);
    scene->addItem(rec4);
    
    
    rec2->moveBy(80,0);
    rec3->moveBy(160,0);
    rec4->moveBy(240,0);
    

    @

    The mouse events are only working from 0% of the rectangle's width to approximately 85%. On the extreme right of the rectangle, nothing happens ....

    Does anybody have an idea please? :)

    Cheers,



  • No idea what I am doing wrong here?

    Thanks,


  • Moderators

    you are not calling the bade class implementation:
    @
    void MyRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
    QGraphicsItem::mousePressEvent(event);
    }
    @
    Since you use the selected state in your paint event this is mandatory.

    I don't know why it works for some parts of your item at all actually.



  • Hello raven,

    Thanks for your answer.
    Unfortunetely, this doesnt change anything, I still have the same issue ...


  • Moderators

    so when you set a break point into your mousePressEvent() handler it wont get even triggered for the non working area? Meaning you really don't receive an event at all?



  • Hi there,

    bq. not calling the bade class implementation:

    I agree with this 100% but think that this is a different issue. So far as I can see "isPressed" and the derived class mousePessEvent are redundant - better to use the provided stuff in the base class.

    Anyway, surely the fact that only 85% of the rect is "enabled" is related to the boudingRect(). I read this in the help :-
    bq. If you want to change the item's bounding rectangle, you must first call prepareGeometryChange()

    Should you be calling this in the override of boundingRect() ? The help is not so clear about where and when this should be called...

    I'm here to learn...

    Tim


  • Moderators

    [quote author="Timothy" date="1381140131"]
    Anyway, surely the fact that only 85% of the rect is "enabled" is related to the boudingRect(). I read this in the help :-
    bq. If you want to change the item's bounding rectangle, you must first call prepareGeometryChange()

    Should you be calling this in the override of boundingRect() ? The help is not so clear about where and when this should be called...
    [/quote]
    the signal has to be triggered whenever it is about to be changed internally (in your implementation). In this case it's static all the time. So this isn't the problem.

    There are still many possibilities why it fails. Do you filter any events to the graphics view or its viewport? Do you have any widgets placed on the viewport?



  • Thanks for your answers guys ...
    @Timothy, here I dont change the boundingRect ...
    @Raven, I dont receive any event at all when on the non working area.
    No widget on the viewport.
    However, myrectangle is a qgraphicswidget and not a qgraphicsitem, could it be the reason?

    class MyRectangle : public QGraphicsWidget

    I need widget for the signals/slots.

    Thanks for your help, I appreciate :)


  • Moderators

    in your very first post you said you inherit from QGraphicsItem.
    If you just need the signal and slot functionality you should use QGraphicsObject.

    So do you filter events?

    It's hard to tell... all i can do is guessing. The code you've posted looks good IMHO. So i guess the problem is probably somewhere else "outside" of this class, since your item doesn't even receive the event.



  • Raven, it inherits from QGraphicsWidget , which is a QGraphicsItem with QObject signal/slot properties.
    Sorry for this correction. However, cant see how this could be the issue.
    I dont filter events, its just a basic test with mouse press event all the code is up there ....



  • I found the issue .... Trying with QGraphicsItem instead of QGraphicsWidget solved the issue ....
    Can't understand why !! Any idea?

    And I need the singnal/slot properties, QGraphicsWidget is supposed to do that, am I mistaken?



  • Hi,

    mouse events depend on the geometry/rect's size which in your case is not set anywhere ... you could print it out and find out it is 50x50 (the default minimum size) for whatever size you'd return in boundingRect() method, so those percents are even not relevant; boundingrect is used in re/drawing operations ...

    you can fix in different ways:

    1. just return rect() in boundingRect() and use setGeometry() in your creation code:

    i.e.

    @MyRectangle *rec = new MyRectangle;
    rec->setGeometry(0,0,60,40);
    ...@

    this way provides flexibility over your widget's custom geometry

    1. leave boundingRect() as it is and resize the widget in paint() method

    i.e.

    @...
    QRectF rec = boundingRect();
    resize(rec.width(),rec.height());
    ...@

    also you can inherit QGraphicsItem which works (it has no local rect , just a bounding one), and to enable signals/slots you must inherit from QObject and use Q_OBJECT macro ...

    Cheers!



  • I understand. Thnk you very much for your explanations. I finally opted for the last solution and its works as expected.

    bq. also you can inherit QGraphicsItem which works (it has no local rect , just a bounding one), and to enable signals/slots you must inherit from QObject and use Q_OBJECT macro …


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.