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.
  • Pl45m4P Pl45m4

    @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).

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #7

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

    Pl45m4P 1 Reply Last reply
    0
    • JonBJ JonB

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

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on 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
      • JonBJ Offline
        JonBJ Offline
        JonB
        wrote on 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!

        Pl45m4P 1 Reply Last reply
        0
        • JonBJ JonB

          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!

          Pl45m4P Offline
          Pl45m4P Offline
          Pl45m4
          wrote on 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

          JonBJ 1 Reply Last reply
          0
          • Pl45m4P Pl45m4

            @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.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on 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
            • JonBJ Offline
              JonBJ Offline
              JonB
              wrote on 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"... !

              Pl45m4P 1 Reply Last reply
              1
              • JonBJ JonB

                @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"... !

                Pl45m4P Offline
                Pl45m4P Offline
                Pl45m4
                wrote on 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
                • JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on 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.

                  Pl45m4P 1 Reply Last reply
                  1
                  • JonBJ JonB has marked this topic as solved on
                  • JonBJ JonB referenced this topic on
                  • JonBJ JonB

                    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.

                    Pl45m4P Offline
                    Pl45m4P Offline
                    Pl45m4
                    wrote on 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

                    JonBJ 1 Reply Last reply
                    0
                    • Pl45m4P Pl45m4

                      @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)

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on 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

                      • Login

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