Results 1 to 2 of 2

Thread: Handle mouse events in widgets from scene

  1. #1
    Join Date
    Aug 2015
    Posts
    5
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Handle mouse events in widgets from scene

    Hello,

    I'm trying to design an interface, and I encounter an issue. I'm trying to create a scene, where I can move a menu inside (with buttons).
    Here is an image of what I have:
    Screen Shot 2015-11-06 at 3.41.55 PM.png

    What I want to achieve, is, when I click somewhere on the scene I move the all menu around the location clicked.
    I was able to do that, but the problem was when I tried to click on one of the button form the menu, it was moving the menu (like if I clicked on the scene).
    I want the scene to ignore the click (do not move the menu) when I click on one button. I kind of managed to do that too, but then when I click somewhere in the QWidget that contains my buttons, the menu doesn't move.

    The big white box on the image containing my button is suppose to be transparent (I just put it white for explanations).

    What I would need would be to have the containing QWidget transparent on click events, but not the buttons inside it.

    Is it possible to do that ?

    Thank you very much.

    Edit: I tried to tweak all mouse events in all combinations possible, but it doesn't work. Is it an implementation problem ? Should I replace my QWidget by a QGraphicsGroupItem ? Would it make a difference ?
    Last edited by whiteShadow; 6th November 2015 at 23:56.

  2. #2
    Join Date
    Aug 2015
    Posts
    5
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Handle mouse events in widgets from scene

    Thanks to anda_skoa, I finally find a way to do it.

    I don't think it's the best way but it works.

    For those having the same issue here is what I did:

    I changed my menu buttons from QPushButton to QGraphicsObject. In my buttons constructor, I set setAcceptHoverEvents(true) to be able to change button color when mouse hover them (I check in the paint() if option.state has the QStyle::State_MouseOver flag on and change Brush if it has).
    I also set the flag ItemIgnoresTransformation because I don't want my buttons to be zoomed in or move when the scene is transformed (but still I can move then programmatically if I want to position them somewhere else on my scene).
    Then I defined boundingRect(), paint() and mousePressEvent(). mousePressEvent accept the event (e->accept()) and emit a signal in my case, because I want to connect my button to slots (which is why I subclassed a QGraphicsObject and not a QGraphicsItem. It's not as good performance wise, but I have a small scene, so it should be fine).

    Then I created a container for these buttons. This class subclass QObject (I wanted some signals/slots here too) AND QGraphicsItemGroup.
    In this constructor I set setHandlesChildEvents(false) because this is just a container, and I want my buttons inside to receive the actual event.

    Finally in my scene, I create a new container, add it to the scene, and created+added buttons in the container. Then I overloaded mousePressEvent in my scene to detect if a click happened on a QGraphicsItem or not. If it's not the case, I accept the event to avoid propagation to other widget, and I do what I have to do when a click on my scene happen.
    If a QGraphicsItem has been clicked, then I just call the QGraphicsScene::mousePressEvent to propagate the events to children (then my container will ignore it because I asked him not to handle child events, and finally the buttons will accept it and react by emit a signal).

    Here is my customScene::mousePressEvent (it's probably not the best way to implement it, so if anyone has some suggestions to improve it, I'll take'em !!! ):

    Qt Code:
    1. void customScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
    2. {
    3. if (event->button() == Qt::LeftButton)
    4. {
    5. QGraphicsItem* item = this->itemAt(event->scenePos(), QTransform());
    6.  
    7. if (!item)
    8. {
    9. // No graphics item has been clicked. The scene handle the event then.
    10. event->accept();
    11.  
    12. // Move probes center
    13. this->centerCrosshair->setPos(event->scenePos());
    14. this->centerCrosshair->show();
    15.  
    16. // Move menu
    17. this->menu->setMenuCenter(event->scenePos().x(), event->scenePos().y());
    18. this->menu->show();
    19.  
    20. // Move pattern
    21. for (int i = 0; i < this->pat.size(); ++i)
    22. {
    23. this->pat[i]->setCenter(event->scenePos().x(), event->scenePos().y());
    24. }
    25. }
    26. }
    27.  
    28. QGraphicsScene::mousePressEvent(event);
    29. }
    To copy to clipboard, switch view to plain text mode 

    I hope this could help some people trying to do the same thing. I spent a couple of days trying to figure this out. Now I read it, it seems trivial, but when you don't know, it's not.

    If anyone has comments or suggestions to improve it, I'd be happy to ear them.

    Thank you.

Similar Threads

  1. Mouse events for different tables: How to handle?
    By robgeek in forum Qt Programming
    Replies: 7
    Last Post: 17th September 2015, 18:59
  2. mouse events between qwidget, scene and items
    By teorias in forum Qt Programming
    Replies: 4
    Last Post: 8th March 2011, 15:16
  3. Replies: 5
    Last Post: 27th April 2010, 12:04
  4. How to intercept mouse events in a scene
    By markmuetz in forum Qt Programming
    Replies: 2
    Last Post: 22nd May 2008, 15:36
  5. QPushButton:: Handle right mouse button events. Easyway?
    By Harvey West in forum Qt Programming
    Replies: 6
    Last Post: 28th February 2007, 17:56

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.