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. QListWidget drag/drop documentation/behaviour
Forum Updated to NodeBB v4.3 + New Features

QListWidget drag/drop documentation/behaviour

Scheduled Pinned Locked Moved Unsolved General and Desktop
25 Posts 3 Posters 4.0k 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

    For certain types of events (e.g. mouse and key events), the event will be propagated to the receiver's parent and so on up to the top-level object if the receiver is not interested in the event (i.e., it returns false).

    (https://doc.qt.io/qt-5/qcoreapplication.html#notify)

    So from my understanding QCoreApp.. notifies "receiver" widget (at least when it comes to mouse- and keyEvent) and propagates upwards to the top-most. Don't know how d'n'd events work, but a dragEvent starts with a mouseClick and mouseMove :)
    Have you found out, which widget actually your "receiver" of your drags onto your QDialog is? The dialog itself? The listWidget? The listWidgets's viewport? Something else?

    I would have suggested to install the eventFilter on another object (like the viewPort of listWidget), if @VRonin hadn't done that...

    Have you tried "simple" mousePress event first? Maybe dropEvents are treated specially

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

    @Pl45m4
    I will look into this tomorrow now.

    The only "sensible" explanation would indeed be if "mouse events go upward". I can see that makes sense. It would also mean that "install an event filter to intercept mouse events" isn't going to work. As per what my code seems to be showing. Which is fine, if installEventFilter() or similar mentioned this.

    Funnily enough, the example there says it does what I want for key presses:

    Here's a KeyPressEater class that eats the key presses of its monitored objects:

    So that would mean it does work for keys, but not for mouse events.

    Which, if true, must be out there on the web. I'm too tired to go search now.

    Or the dragging of items on a QListWidget miraculously by-passes mouse-event-handling, which would be surprising.

    Pl45m4P 1 Reply Last reply
    0
    • JonBJ JonB

      @Pl45m4
      I will look into this tomorrow now.

      The only "sensible" explanation would indeed be if "mouse events go upward". I can see that makes sense. It would also mean that "install an event filter to intercept mouse events" isn't going to work. As per what my code seems to be showing. Which is fine, if installEventFilter() or similar mentioned this.

      Funnily enough, the example there says it does what I want for key presses:

      Here's a KeyPressEater class that eats the key presses of its monitored objects:

      So that would mean it does work for keys, but not for mouse events.

      Which, if true, must be out there on the web. I'm too tired to go search now.

      Or the dragging of items on a QListWidget miraculously by-passes mouse-event-handling, which would be surprising.

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #17

      @JonB

      Just found out, that QListWidget has a different handler when it's in IconMode

      StartDrag

      • https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qlistview.cpp.html#_ZN17QIconModeViewBase15filterStartDragE6QFlagsIN2Qt10DropActionEE

      DropFilter

      • https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qlistview.cpp.html#_ZN17QIconModeViewBase15filterDropEventEP10QDropEvent

      Have you tried the same without using IconMode? Does it work?

      Edit:
      This seems to be similar to your issue.

      • https://www.qtcentre.org/threads/62791-Disabling-drop-over-some-controls
      • https://forum.qt.io/topic/27375/solved-prevent-users-from-moving-icons-in-qlistwidget-iconmode

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

        @JonB

        Just found out, that QListWidget has a different handler when it's in IconMode

        StartDrag

        • https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qlistview.cpp.html#_ZN17QIconModeViewBase15filterStartDragE6QFlagsIN2Qt10DropActionEE

        DropFilter

        • https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qlistview.cpp.html#_ZN17QIconModeViewBase15filterDropEventEP10QDropEvent

        Have you tried the same without using IconMode? Does it work?

        Edit:
        This seems to be similar to your issue.

        • https://www.qtcentre.org/threads/62791-Disabling-drop-over-some-controls
        • https://forum.qt.io/topic/27375/solved-prevent-users-from-moving-icons-in-qlistwidget-iconmode
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #18

        @Pl45m4
        Thank you for this reply, which for some reason I did not see yesterday.

        I got excited from your message, and particularly the https://forum.qt.io/topic/27375/solved-prevent-users-from-moving-icons-in-qlistwidget-iconmode which seemed to be exactly what i was looking for. However, sadly:

        • I have now verified that I see exactly same behaviour in ListMode not just IconMode, so that is not the issue.

        • It is true that per that thread setMovement(QListView::Static) prevents the drag-drop rearrangement within the QListWidget, which is all that person was posting to request. But...

        • Static setting also prevents any kind of drag on the items, so I can no longer drag them to copy to another window.

        So it's an all-or-nothing:

        • Static movement prevents re-arrangement, as I want, but only by disabling any dragging of items out of the QListView as well.

        • The alternatives Free or Snap allow dragging of items out of the QListView, so I need one of those, but then also allow dropping within the QListView to re-arrange, which I do not want.

        So far I have tried every combination and nothing works to allow outward dragging but not internal dropping. And meanwhile any attempt to get at this via an eventFilter() does nothing, as very mysteriously the drag-drop seems to function without generating any events on the QListView (or its viewport() which can be intercepted by the filter. Sigh....

        P.S.
        Found https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qlistview.cpp.html#236 to confirm my findings about setMovement(QListView::Static) being an all-or-nothing for any dragging operation:

        #if QT_CONFIG(draganddrop)
            bool movable = (movement != Static);
            setDragEnabled(movable);
            d->viewport->setAcceptDrops(movable);
        #endif
        

        P.P.S.
        Eureka! So looking at what it's doing inspired me to try in my code (after ui->setupUi(this)):

        ui->listWidget->viewport()->setAcceptDrops(false);
        // or works equally
        ui->listWidget->setAcceptDrops(false);
        

        So... even though I already had acceptDrops checkbox unchecked in Designer on the QListWidget, the fact that QListWidget::movement() needs to be set to something other than QListView::Static to permit any kind of dragging means this internal code makes it so if you have setDragEnabled(true) (which is required) you automatically get setAcceptDrops(true), which is not wanted! Hence my extra line fixes this :)

        Final word: Doesn't have to be setMovement() non-QListView::Static. Also results from setViewMode(QListView::IconMode). See my next post below for further information. Putting in a manual setAcceptDrops(false); after this still fixes for what I want.

        1 Reply Last reply
        1
        • VRoninV VRonin

          I can't really point out on how to translate it into designer but this minimal example works for me. Items can be dragged to the "DropZone" but not internally in the list

          #include <QApplication>
          #include <QListWidget>
          #include <QHBoxLayout>
          #include <QDragEnterEvent>
          #include <QMimeData>
          #include <QDropEvent>
          
          class DropZone : public QWidget{
          public:
              explicit DropZone(QWidget* parent = nullptr)
                  : QWidget(parent)
              {
                  setAcceptDrops(true);
                  setMinimumSize(100,100);
                  setStyleSheet("background-color:red;");
              }
          protected:
              void dragEnterEvent(QDragEnterEvent *event) override
              {
                  event->acceptProposedAction();
              }
              void dropEvent(QDropEvent *event) override
              {
                  event->acceptProposedAction();
              }
          };
          
          class Interceptor : public QWidget{
          public:
              explicit Interceptor(QWidget* parent = nullptr)
                  : QWidget(parent)
                  , listWid(new QListWidget(this))
              {
                  listWid->setDragEnabled(true);
                  listWid->setDragDropMode(QAbstractItemView::DragOnly);
                  listWid->addItem(QStringLiteral("Test"));
                  listWid->addItem(QStringLiteral("Item"));
                  QHBoxLayout* layout = new QHBoxLayout(this);
                  layout->addWidget(listWid);
                  DropZone* dropZone = new DropZone(this);
                  layout->addWidget(dropZone);
              }
          private:
              QListWidget *listWid;
          };
          
          int main(int argc, char *argv[])
          {
              QApplication app(argc,argv);
              Interceptor wid;
              wid.show();
              return app.exec();
          }
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #19

          @VRonin said in QListWidget drag/drop documentation/behaviour:

              listWid->setDragEnabled(true);
              listWid->setDragDropMode(QAbstractItemView::DragOnly);
          

          Dear @VRonin,

          I hope you might take a couple of minutes to look at this --- just OOI and to feel my pain --- since I have spent so much time trying to figure why your sample code does work but that generated from Designer does not.

          I invite you to place the following line above your two lines:

           listWid->setViewMode(QListView::IconMode);
          

          (The only thing I care about is that you can still start a drag, and you cannot drop the drag back in the list widget to cause changed layout.) Everything still works, right?

          Now please move that line to after the original two lines. This is where it ends up from the .ui file/uic generator to ui_....h from setting all these properties. Now try.... You can now drag & drop the items around the list widget to re-arrange them, can't you? Which is what I was wanting to prevent.

          Now that I have figured this I am of course OK going forward. But I should like sympathy for how long it has taken to me to determine what has been going on... ;-)

          Pl45m4P VRoninV 2 Replies Last reply
          0
          • JonBJ JonB

            @VRonin said in QListWidget drag/drop documentation/behaviour:

                listWid->setDragEnabled(true);
                listWid->setDragDropMode(QAbstractItemView::DragOnly);
            

            Dear @VRonin,

            I hope you might take a couple of minutes to look at this --- just OOI and to feel my pain --- since I have spent so much time trying to figure why your sample code does work but that generated from Designer does not.

            I invite you to place the following line above your two lines:

             listWid->setViewMode(QListView::IconMode);
            

            (The only thing I care about is that you can still start a drag, and you cannot drop the drag back in the list widget to cause changed layout.) Everything still works, right?

            Now please move that line to after the original two lines. This is where it ends up from the .ui file/uic generator to ui_....h from setting all these properties. Now try.... You can now drag & drop the items around the list widget to re-arrange them, can't you? Which is what I was wanting to prevent.

            Now that I have figured this I am of course OK going forward. But I should like sympathy for how long it has taken to me to determine what has been going on... ;-)

            Pl45m4P Offline
            Pl45m4P Offline
            Pl45m4
            wrote on last edited by Pl45m4
            #20

            @JonB said in QListWidget drag/drop documentation/behaviour:

            I invite you to place the following line above your two lines:

            The only thing how I could explain it, is that as I've assumed before, the different "modes" are handled independently.
            Default mode is not IconMode. So maybe all the settings you make, only apply for the current mode (intentionally or not?!) and when you switch the viewMode everything resets / defaults, so you can drop the stuff again... oof... :)

            QtDesigner at it's best :P


            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 QListWidget drag/drop documentation/behaviour:

              I invite you to place the following line above your two lines:

              The only thing how I could explain it, is that as I've assumed before, the different "modes" are handled independently.
              Default mode is not IconMode. So maybe all the settings you make, only apply for the current mode (intentionally or not?!) and when you switch the viewMode everything resets / defaults, so you can drop the stuff again... oof... :)

              QtDesigner at it's best :P

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

              @Pl45m4
              As I showed in the code from your woboq file, it's kind of like that, but not completely. Setting IconMode causes a couple of changes to be made. The trouble is, where they put that line in the ui....h file from Designer properties "undoes" some of the other proprieties you have also set there. Without you realising.

              Anyway, I'm good to go now that I know why & what, just "bruised" from the length of the tussle... ;-)

              Pl45m4P 1 Reply Last reply
              1
              • JonBJ JonB

                @Pl45m4
                As I showed in the code from your woboq file, it's kind of like that, but not completely. Setting IconMode causes a couple of changes to be made. The trouble is, where they put that line in the ui....h file from Designer properties "undoes" some of the other proprieties you have also set there. Without you realising.

                Anyway, I'm good to go now that I know why & what, just "bruised" from the length of the tussle... ;-)

                Pl45m4P Offline
                Pl45m4P Offline
                Pl45m4
                wrote on last edited by
                #22

                @JonB said in QListWidget drag/drop documentation/behaviour:

                The trouble is, where they put that line in the ui....h file from Designer properties "undoes" some of the other proprieties you have also set there.

                Yes... so it's impossible to get that behavior you asked for, when using QtDesigner even tho it is theoretically possible because these are just 3 properties. Just a matter of order. If uic will always put it this way... it doesn't work and you don't know why :)

                Another reason to use QtD for placing widgets and other stuff only and do the rest with code :)


                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
                1
                • JonBJ JonB

                  @VRonin said in QListWidget drag/drop documentation/behaviour:

                      listWid->setDragEnabled(true);
                      listWid->setDragDropMode(QAbstractItemView::DragOnly);
                  

                  Dear @VRonin,

                  I hope you might take a couple of minutes to look at this --- just OOI and to feel my pain --- since I have spent so much time trying to figure why your sample code does work but that generated from Designer does not.

                  I invite you to place the following line above your two lines:

                   listWid->setViewMode(QListView::IconMode);
                  

                  (The only thing I care about is that you can still start a drag, and you cannot drop the drag back in the list widget to cause changed layout.) Everything still works, right?

                  Now please move that line to after the original two lines. This is where it ends up from the .ui file/uic generator to ui_....h from setting all these properties. Now try.... You can now drag & drop the items around the list widget to re-arrange them, can't you? Which is what I was wanting to prevent.

                  Now that I have figured this I am of course OK going forward. But I should like sympathy for how long it has taken to me to determine what has been going on... ;-)

                  VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #23

                  @JonB said in QListWidget drag/drop documentation/behaviour:

                  Now please move that line to after the original two lines. This is where it ends up from the .ui file/uic generator to ui_....h from setting all these properties. Now try.... You can now drag & drop the items around the list widget to re-arrange them, can't you? Which is what I was wanting to prevent.

                  Indeed, this is due to QListView::setViewMode overwriting the acceptDrops property (see https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qlistview.cpp.html#_ZN9QListView11setViewModeENS_8ViewModeE). It's been like this since before the Nokia days so I can't easily dig out why this is the case.

                  For people ending up here from a search engine, the solution is to put ui->listWidget->setDragDropMode(QAbstractItemView::DragOnly); in your widget constructor after the call to setupUi()

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  JonBJ 1 Reply Last reply
                  2
                  • VRoninV VRonin

                    @JonB said in QListWidget drag/drop documentation/behaviour:

                    Now please move that line to after the original two lines. This is where it ends up from the .ui file/uic generator to ui_....h from setting all these properties. Now try.... You can now drag & drop the items around the list widget to re-arrange them, can't you? Which is what I was wanting to prevent.

                    Indeed, this is due to QListView::setViewMode overwriting the acceptDrops property (see https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qlistview.cpp.html#_ZN9QListView11setViewModeENS_8ViewModeE). It's been like this since before the Nokia days so I can't easily dig out why this is the case.

                    For people ending up here from a search engine, the solution is to put ui->listWidget->setDragDropMode(QAbstractItemView::DragOnly); in your widget constructor after the call to setupUi()

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

                    @VRonin
                    Thank you for this. You may be able to see why I was so confused!

                    I would also say that as per my comment earlier I actually put in the following (after setupUi()) to address the issue:

                    ui->listWidget->setAcceptDrops(false);
                    

                    I don't know how that compares against your ui->listWidget->setDragDropMode(QAbstractItemView::DragOnly), I can only say it is what is working for me in the situation I described.

                    VRoninV 1 Reply Last reply
                    1
                    • JonBJ JonB

                      @VRonin
                      Thank you for this. You may be able to see why I was so confused!

                      I would also say that as per my comment earlier I actually put in the following (after setupUi()) to address the issue:

                      ui->listWidget->setAcceptDrops(false);
                      

                      I don't know how that compares against your ui->listWidget->setDragDropMode(QAbstractItemView::DragOnly), I can only say it is what is working for me in the situation I described.

                      VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by
                      #25

                      @JonB said in QListWidget drag/drop documentation/behaviour:

                      I don't know how that compares against your ui->listWidget->setDragDropMode(QAbstractItemView::DragOnly)

                      setDragDropMode calls setAcceptDrops so either works

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      1

                      • Login

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