Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] QGraphicsItem::mouseReleaseEvent not called
QtWS25 Last Chance

[Solved] QGraphicsItem::mouseReleaseEvent not called

Scheduled Pinned Locked Moved General and Desktop
16 Posts 5 Posters 21.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    deanc
    wrote on last edited by
    #1

    I have a QGraphicsItem subclass for which mousePressEvent is called, but mouseReleaseEvent isn't. Here's the situation:

    • A ComponentLayoutView class is derived from QGraphicsItem and represents, of course, a Component in the program.
    • Components contain Ports, so there's also a PortLayoutView, also derived from QGraphicsItem.
    • ComponentLayoutView objects create and own PortLayoutViews depending on the number and type of Ports in the Component object. @ComponentLayoutView::ComponentLayoutView(boost::shared_ptr<SimObjectBase> & bs) {
      //
      // Set the input / output port views
      input1 = new PortLayoutView(this, bs->getConsumerPort(1), PortLayoutView::pdLeft);
      @ ComponentLayoutViews are owned by a QGraphicsScene object.
    • We set several flags in the ComponentLayoutView : @setFlags(ItemIsMovable | ItemIsSelectable | ItemSendsGeometryChanges);@ but not in the PortLayoutViews.
    • PortLayoutViews implement mousePressEvent, mouseReleaseEvent, and mouseMoveEvent.

    Most of this seems to work, including the mousePressEvent. However, the mouseReleaseEvent in the PortLayoutView is never called. Is this as expected? What must we do to detect a mouse button release?

    Thanks!

    1 Reply Last reply
    0
    • EddyE Offline
      EddyE Offline
      Eddy
      wrote on last edited by
      #2

      I think you should use the events for the QGraphicsScene instead, which will propagate to the items.

      Qt Certified Specialist
      www.edalsolutions.be

      1 Reply Last reply
      0
      • D Offline
        D Offline
        deanc
        wrote on last edited by
        #3

        I'm sorry, I'm fairly new to Qt. How do QGraphicsScene events propagate to the items?

        1 Reply Last reply
        0
        • EddyE Offline
          EddyE Offline
          Eddy
          wrote on last edited by
          #4

          It's explained in the "docs":http://developer.qt.nokia.com/doc/qt-4.7/qgraphicsscene.html#id-cf2e5af5-ab61-4db6-be20-b8d3d152f5eb.

          Qt Certified Specialist
          www.edalsolutions.be

          1 Reply Last reply
          0
          • EddyE Offline
            EddyE Offline
            Eddy
            wrote on last edited by
            #5

            Also in the QGraphicsItem "docs.":http://doc.qt.nokia.com/4.7/qgraphicsitem.html#events

            Qt Certified Specialist
            www.edalsolutions.be

            1 Reply Last reply
            0
            • D Offline
              D Offline
              deanc
              wrote on last edited by
              #6

              A little more information: I put mouse event handlers in the scene like so: @void Layout2dScene::mousePressEvent (QGraphicsSceneMouseEvent * event)
              {
              QGraphicsScene::mousePressEvent(event);
              QGraphicsItem * item = mouseGrabberItem();
              }

              void Layout2dScene::mouseReleaseEvent (QGraphicsSceneMouseEvent * event)
              {
              QGraphicsItem * item = mouseGrabberItem();
              QGraphicsScene::mouseReleaseEvent(event);
              }
              @ In both cases the item is the ComponentLayoutView object that contains the port view, not the PortLayoutView object. Nevertheless, the mousePressEvent is delivered to the PortLayoutView object that was clicked on. The mouseReleaseEvent goes to a generic handler in QGraphicsItem.

              Must we handle mouse events at the ComponentLayoutView level, then manually figure out which port, if any, the mouse is in? And if so why do mouse press, move, enter, leave, etc., events all seem to go to the PortLayoutView as we expected?

              Thanks!

              1 Reply Last reply
              0
              • D Offline
                D Offline
                deanc
                wrote on last edited by
                #7

                Oh, and just to be clear, PortLayoutView is declared as:
                @class PortLayoutView : public QGraphicsItem
                {
                Q_DECLARE_TR_FUNCTIONS(PortLayoutView)

                public:
                //...
                protected:
                virtual void mousePressEvent (QGraphicsSceneMouseEvent * event);
                virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent * event);
                virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
                @

                1 Reply Last reply
                0
                • EddyE Offline
                  EddyE Offline
                  Eddy
                  wrote on last edited by
                  #8

                  it's hard to see with all those code fragments.

                  Can you make a minimal compilable example so we can try things out.

                  Qt Certified Specialist
                  www.edalsolutions.be

                  1 Reply Last reply
                  0
                  • EddyE Offline
                    EddyE Offline
                    Eddy
                    wrote on last edited by
                    #9

                    One way to determine what's wrong is good old debugging.

                    Put a debug line in every mouseReleaseEvent / mousePressEvent of every QGraphicsView, scene, item you use.
                    That way you will know where the action happens.

                    Hope this helps.

                    Qt Certified Specialist
                    www.edalsolutions.be

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      deanc
                      wrote on last edited by
                      #10

                      Found a solution, but don't know if this is intentional behaviour on Qt's part. Note the commented-out line in the mousePressEvent handler:
                      @void PortLayoutView::mousePressEvent ( QGraphicsSceneMouseEvent * event )
                      {
                      boost::shared_ptr<PortBase> sp = port.lock();
                      if (!sp) return;
                      if (event->buttons() & Qt::LeftButton)
                      {
                      startPos = event->pos();
                      if (event->modifiers() & Qt::ControlModifier)
                      {
                      sp->setConnectionSource();
                      notifyAll(portSelectMsg);
                      }
                      }
                      // QGraphicsItem::mousePressEvent(event);
                      }
                      @
                      Thanks again!

                      1 Reply Last reply
                      0
                      • EddyE Offline
                        EddyE Offline
                        Eddy
                        wrote on last edited by
                        #11

                        bq. Found a solution, but don’t know if this is intentional behaviour on Qt’s part

                        You didn't use the mousepressEvent from the base class and you don't need to if you reimplement it.

                        Good work! glad you made it.

                        Qt Certified Specialist
                        www.edalsolutions.be

                        A 1 Reply Last reply
                        0
                        • D Offline
                          D Offline
                          deanc
                          wrote on last edited by
                          #12

                          What I meant by "intentional behaviour" is that the program behaves differently when the base class handler is called, even if the handler doesn't do anything. One would assume that the QGraphicsItem::mousePressEvent(event); statement would be harmless, if slightly inefficient. This seems to be the case for the other mouse events. Perhaps one day I'll have some time to trace through the Qt source and research this in more depth.

                          Thanks!

                          1 Reply Last reply
                          0
                          • EddyE Offline
                            EddyE Offline
                            Eddy
                            wrote on last edited by
                            #13

                            I'm sure that will be a good learning experience!

                            For the main philosophy "this":http://doc.qt.nokia.com/4.7/graphicsview.html is also a good read.

                            Qt Certified Specialist
                            www.edalsolutions.be

                            1 Reply Last reply
                            0
                            • S Offline
                              S Offline
                              smudibh20
                              wrote on last edited by
                              #14

                              @deanc Thanks a lot for posting brief problem and solution. It solved my problem too.
                              Thanks once again !

                              1 Reply Last reply
                              0
                              • K Offline
                                K Offline
                                Kfazzz
                                wrote on last edited by
                                #15

                                I have a similar problem. I have a QGraphicsScene which hold QGraphicsView as parent. then I got QGraphicsProxyWidget holding myWidget derived from QWidget which can not receive mouseReleaseEvent but no problem receiving mousePressEvent. I have a QLabel and a QPushButton in myWidget Class. I tried debugging but It confused me when tracing into Qt internal class. Then I just simply change myWidget parent from QWidget to QPushButton and it worked. Hope my solution helps.

                                Thanks!

                                1 Reply Last reply
                                0
                                • EddyE Eddy

                                  bq. Found a solution, but don’t know if this is intentional behaviour on Qt’s part

                                  You didn't use the mousepressEvent from the base class and you don't need to if you reimplement it.

                                  Good work! glad you made it.

                                  A Offline
                                  A Offline
                                  Asperamanca
                                  wrote on last edited by
                                  #16

                                  @Eddy said:

                                  You didn't use the mousepressEvent from the base class and you don't need to if you reimplement it.

                                  That's not necessarily true. The base class events implement certain functionality -they may select or deselect items, move items, etc. If you do not call a base class event, you lose that functionality. Worse still, if you reimplement some events, but not other, you might stumble into undefined behavior, as e.g. the base class receives a mouseRelease event where it expected to receive a mousePress first.

                                  Before you decide not to call an event of the base class, you should

                                  • Check which functionality it implements, and whether you can afford to do without it
                                  • Check which events may be tied together, and whether you should reimplement all or none of them
                                  • Think about the alternative of either calling the base class event before or after your custom event code
                                  1 Reply Last reply
                                  0

                                  • Login

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • Users
                                  • Groups
                                  • Search
                                  • Get Qt Extensions
                                  • Unsolved