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. Detect when QGraphicsItem dropped
Forum Updated to NodeBB v4.3 + New Features

Detect when QGraphicsItem dropped

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 3 Posters 868 Views 2 Watching
  • 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.
  • J Offline
    J Offline
    JonB
    wrote on 30 May 2024, 14:45 last edited by
    #1

    Per the title, all I need to know is "when QGraphicsItem dropped"?

    I have a QGraphicsScene, QGraphicsView and some QGraphicsItems on the scene/view. My items have QGraphicsItem::ItemIsMovable flag. I can drag them around the scene/view, and they stay where I drag them to/drop/release mouse, whichever you wish.

    This is all perfect. The only think I need to know is when they are dropped, so that I can run some code. All the examples involve QDrag objects/operations, overriding mouse events, accepting actions, reading mime types, ... Do I really need any of these when everything is working perfectly as-is with none of them but I just need notification when the dragged graphics item is released somewhere at the end of the drag/drop?

    P 1 Reply Last reply 30 May 2024, 15:02
    0
    • J Offline
      J Offline
      JonB
      wrote on 31 May 2024, 13:59 last edited by JonB
      #14

      Well, today I discovered the "missing link" :) There is a QGraphicsScene method QGraphicsItem *QGraphicsScene::mouseGrabberItem() const:

      Returns the current mouse grabber item, or nullptr if no item is currently grabbing the mouse. The mouse grabber item is the item that receives all mouse events sent to the scene.

      An item becomes a mouse grabber when it receives and accepts a mouse press event, and it stays the mouse grabber until either of the following events occur:

      • If the item receives a mouse release event when there are no other buttons pressed, it loses the mouse grab.

      Never came across this in all my searches of people trying to deal with end of ItemIsMovable drag. It's just what I needed. So I can handle this on the scene starting from:

      void MyGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
      {
          QGraphicsItem *grabbedItem = mouseGrabberItem();
      
          QGraphicsScene::mouseReleaseEvent(event);
      
          if (grabbedItem && !mouseGrabberItem())
              emit itemMoved(grabbedItem);
      }
      

      (With a bit more work we could of course discover and save the original scenePos() in a mousePressEvent() and compare in mouseReleaseEvent() to see if different for actual move.) I haven't looked into selecting/moving multiple items yet. But this is all I ever wanted for now :)

      Thanks @Pl45m4 for your interest and help.

      P 1 Reply Last reply 31 May 2024, 15:07
      1
      • J JonB
        30 May 2024, 14:45

        Per the title, all I need to know is "when QGraphicsItem dropped"?

        I have a QGraphicsScene, QGraphicsView and some QGraphicsItems on the scene/view. My items have QGraphicsItem::ItemIsMovable flag. I can drag them around the scene/view, and they stay where I drag them to/drop/release mouse, whichever you wish.

        This is all perfect. The only think I need to know is when they are dropped, so that I can run some code. All the examples involve QDrag objects/operations, overriding mouse events, accepting actions, reading mime types, ... Do I really need any of these when everything is working perfectly as-is with none of them but I just need notification when the dragged graphics item is released somewhere at the end of the drag/drop?

        P Offline
        P Offline
        Pl45m4
        wrote on 30 May 2024, 15:02 last edited by Pl45m4
        #2

        @JonB

        So you want to know when the movable item was released (move operation has stopped)?!
        I also think you don't need QDrop for this.

        What about a mix of QGraphicsItem::mousePressEvent, QGraphicsItem::mouseMoveEvent and QGraphicsItem::mouseReleaseEvent?
        Have you tried using these 3 in combination?
        When the moving has stopped and the mouse was released, the item was "dropped", right?!


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        J 1 Reply Last reply 30 May 2024, 17:27
        0
        • P Pl45m4
          30 May 2024, 15:02

          @JonB

          So you want to know when the movable item was released (move operation has stopped)?!
          I also think you don't need QDrop for this.

          What about a mix of QGraphicsItem::mousePressEvent, QGraphicsItem::mouseMoveEvent and QGraphicsItem::mouseReleaseEvent?
          Have you tried using these 3 in combination?
          When the moving has stopped and the mouse was released, the item was "dropped", right?!

          J Offline
          J Offline
          JonB
          wrote on 30 May 2024, 17:27 last edited by JonB
          #3

          @Pl45m4
          If I have to. But why do I have to do all this? The move of the QGraphicsItem by dragging is already working 100%. I simply want to know where it ends up/that the drag has finished. Which Qt certainly knows. And there will be other mouseReleaseEvents (e.g. clicking) which I will have to distinguish from "end of drag". This really ought be easy, knowing when a item has been dragged and it's done dragging is a common enough thing to want to write code on.

          J 1 Reply Last reply 30 May 2024, 17:32
          0
          • J JonB
            30 May 2024, 17:27

            @Pl45m4
            If I have to. But why do I have to do all this? The move of the QGraphicsItem by dragging is already working 100%. I simply want to know where it ends up/that the drag has finished. Which Qt certainly knows. And there will be other mouseReleaseEvents (e.g. clicking) which I will have to distinguish from "end of drag". This really ought be easy, knowing when a item has been dragged and it's done dragging is a common enough thing to want to write code on.

            J Offline
            J Offline
            JoeCFD
            wrote on 30 May 2024, 17:32 last edited by
            #4

            @JonB https://doc.qt.io/qt-5/qgraphicsitem.html#dragLeaveEvent ?

            J 1 Reply Last reply 30 May 2024, 19:03
            0
            • J JoeCFD
              30 May 2024, 17:32

              @JonB https://doc.qt.io/qt-5/qgraphicsitem.html#dragLeaveEvent ?

              J Offline
              J Offline
              JonB
              wrote on 30 May 2024, 19:03 last edited by JonB
              #5

              @JoeCFD
              I don't think it would be that gfx item event.

              QGraphicsScene::dropEvent(QGraphicsSceneDragDropEvent *event) seems more like it to me. But from the QGraphicsSceneDragDropEvent I don't see how I get the QGraphicsItem item which was dropped/moved (if you can, show me how)....

              With the QGraphicsItem::ItemIsMovable flag set, when it allows you to drag a QGraphicsItem around, is that "drag and drop"?

              UPDATE
              https://www.qtcentre.org/threads/63321-QGraphicsItem-ItemIsMovable-in-QGraphicsScene-add-actions-on-drop

              If you move the pixmap item, then there is no drag&drop involved at all.

              Thanks, I got confused, I needed to use mouseReleaseEvent

              P 1 Reply Last reply 30 May 2024, 19:06
              0
              • J JonB
                30 May 2024, 19:03

                @JoeCFD
                I don't think it would be that gfx item event.

                QGraphicsScene::dropEvent(QGraphicsSceneDragDropEvent *event) seems more like it to me. But from the QGraphicsSceneDragDropEvent I don't see how I get the QGraphicsItem item which was dropped/moved (if you can, show me how)....

                With the QGraphicsItem::ItemIsMovable flag set, when it allows you to drag a QGraphicsItem around, is that "drag and drop"?

                UPDATE
                https://www.qtcentre.org/threads/63321-QGraphicsItem-ItemIsMovable-in-QGraphicsScene-add-actions-on-drop

                If you move the pixmap item, then there is no drag&drop involved at all.

                Thanks, I got confused, I needed to use mouseReleaseEvent

                P Offline
                P Offline
                Pl45m4
                wrote on 30 May 2024, 19:06 last edited by
                #6

                @JonB said in Detect when QGraphicsItem dropped:

                With the QGraphicsItem::ItemIsMovable flag set, when it allows you to drag a QGraphicsItem around, is that "drag and drop"?

                I don't think so... that's why I wrote my comment above...
                ItemIsMovable and QDrag / QDrop are two different pair of shoes. The latter occures when dragging an item from another place to the scene (or from one scene to another).


                If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                ~E. W. Dijkstra

                J 1 Reply Last reply 30 May 2024, 19:07
                1
                • P Pl45m4
                  30 May 2024, 19:06

                  @JonB said in Detect when QGraphicsItem dropped:

                  With the QGraphicsItem::ItemIsMovable flag set, when it allows you to drag a QGraphicsItem around, is that "drag and drop"?

                  I don't think so... that's why I wrote my comment above...
                  ItemIsMovable and QDrag / QDrop are two different pair of shoes. The latter occures when dragging an item from another place to the scene (or from one scene to another).

                  J Offline
                  J Offline
                  JonB
                  wrote on 30 May 2024, 19:07 last edited by JonB
                  #7

                  @Pl45m4 Absolutely, just got that, your post crossed with my update. Will investigate tomorrow.

                  P 1 Reply Last reply 30 May 2024, 19:16
                  0
                  • J JonB
                    30 May 2024, 19:07

                    @Pl45m4 Absolutely, just got that, your post crossed with my update. Will investigate tomorrow.

                    P Offline
                    P Offline
                    Pl45m4
                    wrote on 30 May 2024, 19:16 last edited by
                    #8

                    @JonB

                    An idea just came to my mind, let me cook, will report later :D


                    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                    ~E. W. Dijkstra

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      JonB
                      wrote on 30 May 2024, 19:24 last edited by JonB
                      #9

                      I will still have to recognise this is the release at the of an item-move, not e.g. just a click, and which item has been moved.... Seems a shame, I was expecting/hoping for something like an event at the end of the item move, with the QGraphicsItem moved as an argument.

                      It seems so simple: I just moved an item I set ItemIsMovable on, could you tell me which item just finished getting moved? Mine cannot be the only application which needs to act on that!

                      P 1 Reply Last reply 30 May 2024, 20:11
                      0
                      • J JonB
                        30 May 2024, 19:24

                        I will still have to recognise this is the release at the of an item-move, not e.g. just a click, and which item has been moved.... Seems a shame, I was expecting/hoping for something like an event at the end of the item move, with the QGraphicsItem moved as an argument.

                        It seems so simple: I just moved an item I set ItemIsMovable on, could you tell me which item just finished getting moved? Mine cannot be the only application which needs to act on that!

                        P Offline
                        P Offline
                        Pl45m4
                        wrote on 30 May 2024, 20:11 last edited by
                        #10

                        @JonB

                        You've commented on a similar topic two years ago :)

                        • https://forum.qt.io/topic/141737/qgraphicsitem-movement-detection

                        My idea was to use QGraphicsItem::itemChange, but turned out, it's not better than using ::mouseReleaseEvent, ::mousePressEvent and ::mouseMoveEvent.


                        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                        ~E. W. Dijkstra

                        J 1 Reply Last reply 30 May 2024, 20:21
                        0
                        • P Pl45m4
                          30 May 2024, 20:11

                          @JonB

                          You've commented on a similar topic two years ago :)

                          • https://forum.qt.io/topic/141737/qgraphicsitem-movement-detection

                          My idea was to use QGraphicsItem::itemChange, but turned out, it's not better than using ::mouseReleaseEvent, ::mousePressEvent and ::mouseMoveEvent.

                          J Offline
                          J Offline
                          JonB
                          wrote on 30 May 2024, 20:21 last edited by JonB
                          #11

                          @Pl45m4 said in Detect when QGraphicsItem dropped:

                          You've commented on a similar topic two years ago :)

                          Perfect! Lots of information there! No recollection, that's what senility does for you.

                          So unless there is a "move operation complete" signal (end of drag? drop? but not sure there is one) just recognise "mouse release" event and query pos() then. You could compare that against original position to see if moved, or set a flag for "moved" when get itemPositionHasChanged signal. Then emit your own signal for the end-of-move-with-position

                          I wrote that, it's what I was just thinking now. I am OK with subclassing, unlike the OP in that thread.

                          Now that I have seen https://doc.qt.io/qt-6/qgraphicsitem.html#GraphicsItemFlag-enum

                          QGraphicsItem::ItemIsMovable
                          This feature is provided as a convenience through the base implementation of QGraphicsItem's mouse event handlers.

                          I'm much clearer :)

                          1 Reply Last reply
                          0
                          • J Offline
                            J Offline
                            JonB
                            wrote on 31 May 2024, 10:30 last edited by JonB
                            #12

                            @Pl45m4
                            I have now had a chance to look at (I don't have Qt sources) ItemIsMovable in Qt woboq sources. in https://codebrowser.dev/qt5/qtbase/src/widgets/graphicsview/qgraphicsitem.cpp.html. Much happier now that I can see how/when/what it does!

                            As an aside, as per QGraphicsItem::mouseMoveEvent() at https://codebrowser.dev/qt5/qtbase/src/widgets/graphicsview/qgraphicsitem.cpp.html#7314, if you look at the amount of code handling particularly multiitem movement (which I will probably need) it seems to me to give the lie to people on the web who say "don't bother to use ItemIsMovable, simply switch if off and do it yourself in mouse events"... !

                            P 1 Reply Last reply 31 May 2024, 12:51
                            1
                            • J JonB
                              31 May 2024, 10:30

                              @Pl45m4
                              I have now had a chance to look at (I don't have Qt sources) ItemIsMovable in Qt woboq sources. in https://codebrowser.dev/qt5/qtbase/src/widgets/graphicsview/qgraphicsitem.cpp.html. Much happier now that I can see how/when/what it does!

                              As an aside, as per QGraphicsItem::mouseMoveEvent() at https://codebrowser.dev/qt5/qtbase/src/widgets/graphicsview/qgraphicsitem.cpp.html#7314, if you look at the amount of code handling particularly multiitem movement (which I will probably need) it seems to me to give the lie to people on the web who say "don't bother to use ItemIsMovable, simply switch if off and do it yourself in mouse events"... !

                              P Offline
                              P Offline
                              Pl45m4
                              wrote on 31 May 2024, 12:51 last edited by Pl45m4
                              #13

                              @JonB said in Detect when QGraphicsItem dropped:

                              As an aside, as per QGraphicsItem::mouseMoveEvent() at https://codebrowser.dev/qt5/qtbase/src/widgets/graphicsview/qgraphicsitem.cpp.html#7314, if you look at the amount of code handling particularly multiitem movement (which I will probably need) it seems to me to give the lie to people on the web who say "don't bother to use ItemIsMovable, simply switch if off and do it yourself in mouse events"... !

                              I know, have also seen this.
                              The actual move (setPos) call happens in L.7382. So almost 70 LoC to handle all transformations, selection groups, parent/childs that should move together, etc...

                              Yeah, doing all this by yourself, while paying attention to every "trap" (e.g. not to detach the items from QList selectedItems, as noted in the mouseMoveEvent Impl.), might be tricky.
                              And is, for sure, more pain in the programmer's butt, than simply calling setFlag(ItemIsMovable) :)


                              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                              ~E. W. Dijkstra

                              1 Reply Last reply
                              0
                              • J Offline
                                J Offline
                                JonB
                                wrote on 31 May 2024, 13:59 last edited by JonB
                                #14

                                Well, today I discovered the "missing link" :) There is a QGraphicsScene method QGraphicsItem *QGraphicsScene::mouseGrabberItem() const:

                                Returns the current mouse grabber item, or nullptr if no item is currently grabbing the mouse. The mouse grabber item is the item that receives all mouse events sent to the scene.

                                An item becomes a mouse grabber when it receives and accepts a mouse press event, and it stays the mouse grabber until either of the following events occur:

                                • If the item receives a mouse release event when there are no other buttons pressed, it loses the mouse grab.

                                Never came across this in all my searches of people trying to deal with end of ItemIsMovable drag. It's just what I needed. So I can handle this on the scene starting from:

                                void MyGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
                                {
                                    QGraphicsItem *grabbedItem = mouseGrabberItem();
                                
                                    QGraphicsScene::mouseReleaseEvent(event);
                                
                                    if (grabbedItem && !mouseGrabberItem())
                                        emit itemMoved(grabbedItem);
                                }
                                

                                (With a bit more work we could of course discover and save the original scenePos() in a mousePressEvent() and compare in mouseReleaseEvent() to see if different for actual move.) I haven't looked into selecting/moving multiple items yet. But this is all I ever wanted for now :)

                                Thanks @Pl45m4 for your interest and help.

                                P 1 Reply Last reply 31 May 2024, 15:07
                                1
                                • J JonB has marked this topic as solved on 31 May 2024, 14:00
                                • J JonB referenced this topic on 31 May 2024, 14:22
                                • J JonB
                                  31 May 2024, 13:59

                                  Well, today I discovered the "missing link" :) There is a QGraphicsScene method QGraphicsItem *QGraphicsScene::mouseGrabberItem() const:

                                  Returns the current mouse grabber item, or nullptr if no item is currently grabbing the mouse. The mouse grabber item is the item that receives all mouse events sent to the scene.

                                  An item becomes a mouse grabber when it receives and accepts a mouse press event, and it stays the mouse grabber until either of the following events occur:

                                  • If the item receives a mouse release event when there are no other buttons pressed, it loses the mouse grab.

                                  Never came across this in all my searches of people trying to deal with end of ItemIsMovable drag. It's just what I needed. So I can handle this on the scene starting from:

                                  void MyGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
                                  {
                                      QGraphicsItem *grabbedItem = mouseGrabberItem();
                                  
                                      QGraphicsScene::mouseReleaseEvent(event);
                                  
                                      if (grabbedItem && !mouseGrabberItem())
                                          emit itemMoved(grabbedItem);
                                  }
                                  

                                  (With a bit more work we could of course discover and save the original scenePos() in a mousePressEvent() and compare in mouseReleaseEvent() to see if different for actual move.) I haven't looked into selecting/moving multiple items yet. But this is all I ever wanted for now :)

                                  Thanks @Pl45m4 for your interest and help.

                                  P Offline
                                  P Offline
                                  Pl45m4
                                  wrote on 31 May 2024, 15:07 last edited by Pl45m4
                                  #15

                                  @JonB said in Detect when QGraphicsItem dropped:

                                  There is a QGraphicsScene method QGraphicsItem *QGraphicsScene::mouseGrabberItem() const:

                                  Great find, but if I understand this correctly, things could become tricky because of:

                                  If the item loses its mouse grab, the scene will ignore all mouse events until a new item grabs the mouse (i.e., until a new item receives a mouse press event).

                                  From my understanding the scene is then unable to process any mouse event other than grabbing an item?!
                                  Might work in your case, but any kind of user-defined selection or mouse interaction "stuff" would be omitted though?!
                                  (don't know, not tested)
                                  (looking at QRubberBand or whatever you possibly have in your scene)


                                  If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                                  ~E. W. Dijkstra

                                  J 1 Reply Last reply 31 May 2024, 15:17
                                  0
                                  • P Pl45m4
                                    31 May 2024, 15:07

                                    @JonB said in Detect when QGraphicsItem dropped:

                                    There is a QGraphicsScene method QGraphicsItem *QGraphicsScene::mouseGrabberItem() const:

                                    Great find, but if I understand this correctly, things could become tricky because of:

                                    If the item loses its mouse grab, the scene will ignore all mouse events until a new item grabs the mouse (i.e., until a new item receives a mouse press event).

                                    From my understanding the scene is then unable to process any mouse event other than grabbing an item?!
                                    Might work in your case, but any kind of user-defined selection or mouse interaction "stuff" would be omitted though?!
                                    (don't know, not tested)
                                    (looking at QRubberBand or whatever you possibly have in your scene)

                                    J Offline
                                    J Offline
                                    JonB
                                    wrote on 31 May 2024, 15:17 last edited by JonB
                                    #16

                                    @Pl45m4
                                    I don't know but I don't think I care. It's not my responsibility. I am not doing anything other than looking at QGraphicsScene::mouseGrabberItem() in mouseReleaseEvent(). I am not doing anything to affect/alter how Qt infrastructure handles that, I am not in any way altering whatever ItemIsMovable does (or does not) do. To be clear, I find that if I am dragging/moving an item when MyGraphicsScene::mouseReleaseEvent() is hit then on entry mouseGrabberItem() returns the QGraphicsItem being pressed/moved, if any, and then after I call the base QGraphicsScene::mouseReleaseEvent(event); in the middle mouseGrabberItem() then returns nullptr, i.e. it got "released". And my code concludes by saying "if there was a grabbed item on entry and now there is no grabbed item after processing the mouse release then emit a signal saying that item (may) have moved. Which a slot on the signal then decides to look at the item and do whatever (e.g. look where it is now and if necessary adjust some internal information about that).

                                    I don't see any flaw in that, I just want to be notified that an item has (possibly) moved (when it has finished being moved)?

                                    1 Reply Last reply
                                    0

                                    1/16

                                    30 May 2024, 14:45

                                    • Login

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