Detecting clicks outside of widgets while still having widgets deal with keypresses that occur within them.



  • I'm trying to make a basic application that lets you click in two locations to define a line (e.g. I click at point (0,0) and point (10, 10) and a line is drawn between those two points).

    Additionally, I'd like to have a rectangle widget that I can click and drag around.

    I already have the rectangle working correctly, but now I'm running into issues detecting keyPresses in the main view.

    I have a custom class that inherits from QGraphicsView and overrides the following methods:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

    When I implement these methods however, my program completely ignores the mousePressEvent methods I have within my rectangle class (as they are all caught by these methods first).

    Is there a way to catch clicks within my view ONLY when they're not inside a widget (otherwise catch them within the widget)?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Are you calling the base class implementation of these methods in your reimplementation ?



  • @SGaist

    I don't believe so.

    In MyView I have:

    void MyView::mousePressEvent(QMouseEvent *event)
    {
    std::cout << "CLICKED IN VIEW\n" << std::endl;
    }

    and in MyRectangle I have:
    void MyRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
    std::cout << "CLICKED IN Rectangle!\n" << std::endl;
    }

    Currently all clicks are printing "CLICKED IN VIEW", even if it's actually inside the rectangle.



  • Bump. I still can't figure this out.

    The best way I can figure to do it currently is keep a list of MyRectangle's inside MyView and then manually pass the event like so:

    void MyView::mousePressEvent(QMouseEvent *event)
    {
        std::cout << "CLICKED IN VIEW\n" << std::endl;
    
        for (std::vector<MyRectangle*>::iterator it = rectangles.begin(); it != rectangles.end(); ++it)
        {
     	
    	    ((MyRectangle*)*it)->mousePressEvent(event);
    	
        }
    }
    

    this seems really barbaric though and I'm hoping there's just some way to do something like passEventToChildren(event)


  • Lifetime Qt Champion

    Again: you are not calling the base class implementation, so you are interrupting the normal event delivery.

    void MyView::mousePressEvent(QMouseEvent *event){
        qDebug() << "Clicked in view";
        QGraphicsView::mousePressEvent(event);
    }
    


  • @SGaist said:

    Again: you are not calling the base class implementation, so you are interrupting the normal event delivery.

    void MyView::mousePressEvent(QMouseEvent *event){
        qDebug() << "Clicked in view";
        QGraphicsView::mousePressEvent(event);
    }
    

    This worked perfectly. Sorry, I thought you were making sure I WASN'T calling the base class implementation.


  • Lifetime Qt Champion

    No problem :)

    Since you have it working now, please update the thread title prepending [solved] so other forum users may know a solution has been found :)


Log in to reply
 

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