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 Update on Monday, May 27th 2025

QListWidget drag/drop documentation/behaviour

Scheduled Pinned Locked Moved Unsolved General and Desktop
25 Posts 3 Posters 3.9k 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.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #1

    I do not understand how the documentation and behaviour of QListWidget drag/drop relate to each other. Perhaps some expert on Qt behaviour or the way they use the English language in the documentation could enlighten me :)

    I am in Designer. I start with a default QListWidget. (If it makes any difference, note that my viewMode is set to IconMode.) Note that at this point:

    • dragEnabled is unchecked
    • dragDropMode is NoDragDrop
    • defaultDropAction is CopyAction

    I add some QListWidgetItem items (via Edit Items...).

    At this point I cannot drag any items. Good.

    I change to check dragEnabled and I set dragDropMode to DragOnly, or any other allowable for drag.

    I still cannot drag any items. Not so good. To me the documentation implies this should now be allowed.

    On an item's Properties I now check DragEnabled. That item is now draggable.

    Good, but confusing.

    I find that only each item's individual DragEnabled has any effect. I do not find that the QListView's dragEnabled setting influences this either way, nor its dragDropMode. I do not get that from the documentation, e.g. What is the point of them?

    When you have explained that, you may (optionally) tell me whether what I would like is really achievable. Remember that my viewMode is set to IconMode, if that is relevant.

    • I want to be able to drag the icons from the QListView to elsewhere. This works.
    • I want CopyAction, so that when dragging elsewhere the icon does not move out of the list view. This works.
    • I do not want the user to be able to drag the items within the QListWidget. At present this is allowed, so that the icon is moved around the widget. I do not want to allow this, but cannot find a setting which prevents this (while still allowing drag out from the widget)?
    VRoninV 1 Reply Last reply
    0
    • JonBJ JonB

      I do not understand how the documentation and behaviour of QListWidget drag/drop relate to each other. Perhaps some expert on Qt behaviour or the way they use the English language in the documentation could enlighten me :)

      I am in Designer. I start with a default QListWidget. (If it makes any difference, note that my viewMode is set to IconMode.) Note that at this point:

      • dragEnabled is unchecked
      • dragDropMode is NoDragDrop
      • defaultDropAction is CopyAction

      I add some QListWidgetItem items (via Edit Items...).

      At this point I cannot drag any items. Good.

      I change to check dragEnabled and I set dragDropMode to DragOnly, or any other allowable for drag.

      I still cannot drag any items. Not so good. To me the documentation implies this should now be allowed.

      On an item's Properties I now check DragEnabled. That item is now draggable.

      Good, but confusing.

      I find that only each item's individual DragEnabled has any effect. I do not find that the QListView's dragEnabled setting influences this either way, nor its dragDropMode. I do not get that from the documentation, e.g. What is the point of them?

      When you have explained that, you may (optionally) tell me whether what I would like is really achievable. Remember that my viewMode is set to IconMode, if that is relevant.

      • I want to be able to drag the icons from the QListView to elsewhere. This works.
      • I want CopyAction, so that when dragging elsewhere the icon does not move out of the list view. This works.
      • I do not want the user to be able to drag the items within the QListWidget. At present this is allowed, so that the icon is moved around the widget. I do not want to allow this, but cannot find a setting which prevents this (while still allowing drag out from the widget)?
      VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

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

      I do not want the user to be able to drag the items within the QListWidget. At present this is allowed, so that the icon is moved around the widget. I do not want to allow this, but cannot find a setting which prevents this (while still allowing drag out from the widget)?

      Reimplement QListWidget::supportedDropActions() to return Qt::IgnoreAction (you can then promote your widget from designer to your custom one)

      Good, but confusing.

      DragEnabled is specific, dragEnabled/dragDropMode are generic. The latter applies to the entire view, the former allows the model to customise the behaviour of every single item so, naturally, this prevails as it's more specific

      "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:

        I do not want the user to be able to drag the items within the QListWidget. At present this is allowed, so that the icon is moved around the widget. I do not want to allow this, but cannot find a setting which prevents this (while still allowing drag out from the widget)?

        Reimplement QListWidget::supportedDropActions() to return Qt::IgnoreAction (you can then promote your widget from designer to your custom one)

        Good, but confusing.

        DragEnabled is specific, dragEnabled/dragDropMode are generic. The latter applies to the entire view, the former allows the model to customise the behaviour of every single item so, naturally, this prevails as it's more specific

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

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

        Reimplement QListWidget::supportedDropActions() to return Qt::IgnoreAction (you can then promote your widget from designer to your custom one)

        Damn. I respect what you're saying, I specifically do not want to subclass and Promote. Personal preference. Any way to do it in back-end code without subclassing/changing in Designer?

        DragEnabled is specific, dragEnabled/dragDropMode are generic. The latter applies to the entire view, the former allows the model to customise the behaviour of every single item so, naturally, this prevails as it's more specific

        As clear as mud to me from the docs, which they might have mentioned, but don't. So that I understand, are you saying those properties apply only to whatever is in the QListWidget but outside of any QListWidgetItems on it?

        VRoninV 1 Reply Last reply
        0
        • JonBJ JonB

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

          Reimplement QListWidget::supportedDropActions() to return Qt::IgnoreAction (you can then promote your widget from designer to your custom one)

          Damn. I respect what you're saying, I specifically do not want to subclass and Promote. Personal preference. Any way to do it in back-end code without subclassing/changing in Designer?

          DragEnabled is specific, dragEnabled/dragDropMode are generic. The latter applies to the entire view, the former allows the model to customise the behaviour of every single item so, naturally, this prevails as it's more specific

          As clear as mud to me from the docs, which they might have mentioned, but don't. So that I understand, are you saying those properties apply only to whatever is in the QListWidget but outside of any QListWidgetItems on it?

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

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

          Any way to do it in back-end code without subclassing/changing in Designer?

          The only thing I can think of is to separate it into QListView+ subclassed QStandardItemModel to get rid of the drop

          As clear as mud to me from the docs

          Don't disagree. QListWidget is just a QListView with a model pre-attached to it so it still follows the model-view philosophy even if it's a single widget.

          "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
          0
          • VRoninV VRonin

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

            Any way to do it in back-end code without subclassing/changing in Designer?

            The only thing I can think of is to separate it into QListView+ subclassed QStandardItemModel to get rid of the drop

            As clear as mud to me from the docs

            Don't disagree. QListWidget is just a QListView with a model pre-attached to it so it still follows the model-view philosophy even if it's a single widget.

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

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

            The only thing I can think of is to separate it into QListView+ subclassed QStandardItemModel to get rid of the drop

            Thanks. Not convenient from UI Designer POV. I was about to go look at: can I attach a QListWidget::installEventFilter() and deal with preventing the move/drop event there?

            1 Reply Last reply
            0
            • JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              Well I thought I'd give the concept a try:

              ui->listWidget->installEventFilter(this);
              
              /*virtual*/ bool SomeDialog::eventFilter(QObject *obj, QEvent *ev) /*override*/
              {
                  if (obj == ui->listWidget)
                  {
                      return true;
                  }
                  return QDialog::eventFilter(obj, ev);
              }
              

              This was to filter out all events targeted at ui->listWidget as a starting point, then see what to do about drag/drops. But with above code the QListWidget is still perfectly happy letting me drag/re-arrange its items. Does that not involve any event sent to ui->listWidget, or have I done something wrong?

              1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #7

                You decided to go down the hard route! try if (obj == ui->listWidget->viewPort())

                "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
                0
                • VRoninV VRonin

                  You decided to go down the hard route! try if (obj == ui->listWidget->viewPort())

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

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

                  ui->listWidget->viewPort()

                  Nope :( Items are just as dragable as they were before :( [UPDATE With a qDebug() no events at all arrive for viewport()?]

                  There is a tiny difference, in that first way the items are not shown initially, doubtless from ignoring some showEvent? (The items get shown first time I click into the list widget.) Now they are visible from the start as they used to be. Yet dragging continues.

                  Surely the drag must involve some event to the QListWidget or its viewport? For example, there's just a mouse-down to start the drag, how's that even getting through...?

                  VRoninV 1 Reply Last reply
                  0
                  • JonBJ JonB

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

                    ui->listWidget->viewPort()

                    Nope :( Items are just as dragable as they were before :( [UPDATE With a qDebug() no events at all arrive for viewport()?]

                    There is a tiny difference, in that first way the items are not shown initially, doubtless from ignoring some showEvent? (The items get shown first time I click into the list widget.) Now they are visible from the start as they used to be. Yet dragging continues.

                    Surely the drag must involve some event to the QListWidget or its viewport? For example, there's just a mouse-down to start the drag, how's that even getting through...?

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

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

                    Surely the drag must involve some event to the QListWidget or its viewport? For example, there's justa mouse-down to start the drag, how's that even getting through...?

                    Yep, it's started by the mouseMoveEvent of the view: https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qabstractitemview.cpp.html#1863

                    "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
                    1
                    • VRoninV VRonin

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

                      Surely the drag must involve some event to the QListWidget or its viewport? For example, there's justa mouse-down to start the drag, how's that even getting through...?

                      Yep, it's started by the mouseMoveEvent of the view: https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qabstractitemview.cpp.html#1863

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

                      @VRonin
                      Thanks. So to be clear: the mouse and other events go to my QListWidget first/directly, and (without sub classing) I cannot "intercept" them up at the containing QDialog first, even if I ask nicely?

                      I kinda thought this was the point of an installEventFilter() on, say, a QDialog holding widgets, so that I could intercept the events up at the dialog instead of letting them into the sub-widgets? It's a lot more limited as it seems to stand.

                      Pl45m4P 1 Reply Last reply
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #11

                        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();
                        }
                        

                        "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 2 Replies Last reply
                        0
                        • 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 JonB
                          #12

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

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

                          So far as I can understand, this is all you do in the list widget source (your DropZone is just the target). And I do those two lines from the UI/in the ui_....h file, because I thought like you that QAbstractItemView::DragOnly is what would stop re-ordering. But as I said I can still re-order.

                          I did say earlier I have

                          (If it makes any difference, note that my viewMode is set to IconMode.)

                          Maybe this is an issue? When i put it in I remember the docs saying something about this set some "Free Movement", or similar, flag/option, maybe that's to do with what we are seeing.... [EDIT: I switched over to the normal view but that did not alter the behaviour, so it doesn't seem this is relevant,]

                          1 Reply Last reply
                          0
                          • JonBJ JonB

                            @VRonin
                            Thanks. So to be clear: the mouse and other events go to my QListWidget first/directly, and (without sub classing) I cannot "intercept" them up at the containing QDialog first, even if I ask nicely?

                            I kinda thought this was the point of an installEventFilter() on, say, a QDialog holding widgets, so that I could intercept the events up at the dialog instead of letting them into the sub-widgets? It's a lot more limited as it seems to stand.

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

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

                            I kinda thought this was the point of an installEventFilter() on, say, a QDialog holding widgets, so that I could intercept the events up at the dialog instead of letting them into the sub-widgets? It's a lot more limited as it seems to stand.

                            Aren't events propagated upwards the parent-child-tree starting from the child which is at the given coords?!
                            So it's like:
                            Top-most widget (in your case: QListWidget) recieves drag/mouse/whatever event -> Accept? Yes/no? If yes, it starts to process the event, if not accepted, the event is propagated to the direct/next parent. Then it starts all over again.

                            Old, but still nice to read:

                            • https://www.qt.io/blog/2006/05/27/mouse-event-propagation

                            I kinda thought this was the point of an installEventFilter() on, say, a QDialog holding widgets, so that I could intercept the events up at the dialog instead of letting them into the sub-widgets?

                            That should work. If you install the filter on your dialog and set a target to get "inspected" you can pre-handle the events before they get to the target.


                            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 kinda thought this was the point of an installEventFilter() on, say, a QDialog holding widgets, so that I could intercept the events up at the dialog instead of letting them into the sub-widgets? It's a lot more limited as it seems to stand.

                              Aren't events propagated upwards the parent-child-tree starting from the child which is at the given coords?!
                              So it's like:
                              Top-most widget (in your case: QListWidget) recieves drag/mouse/whatever event -> Accept? Yes/no? If yes, it starts to process the event, if not accepted, the event is propagated to the direct/next parent. Then it starts all over again.

                              Old, but still nice to read:

                              • https://www.qt.io/blog/2006/05/27/mouse-event-propagation

                              I kinda thought this was the point of an installEventFilter() on, say, a QDialog holding widgets, so that I could intercept the events up at the dialog instead of letting them into the sub-widgets?

                              That should work. If you install the filter on your dialog and set a target to get "inspected" you can pre-handle the events before they get to the target.

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

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

                              That should work. If you install the filter on your dialog and set a target to get "inspected" you can pre-handle the events before they get to the target.

                              Is that not exactly what I show I have done in my code?? ui->listWidget->installEventFilter(this); ?

                              Aren't events propagated upwards the parent-child-tree starting from the child which is at the given coords?!

                              How would an event filter on a parent to filter out mouse events to a child work, if the child gets the event first? What's the damn point of an event filter?! ;-)

                              Is this a rodent-only issue? Because I can't see how event filters are working with rodents..... And if the docs know they won't work right with rodents but will with other types of event, I wish they would say so.

                              Pl45m4P 1 Reply Last reply
                              1
                              • JonBJ JonB

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

                                That should work. If you install the filter on your dialog and set a target to get "inspected" you can pre-handle the events before they get to the target.

                                Is that not exactly what I show I have done in my code?? ui->listWidget->installEventFilter(this); ?

                                Aren't events propagated upwards the parent-child-tree starting from the child which is at the given coords?!

                                How would an event filter on a parent to filter out mouse events to a child work, if the child gets the event first? What's the damn point of an event filter?! ;-)

                                Is this a rodent-only issue? Because I can't see how event filters are working with rodents..... And if the docs know they won't work right with rodents but will with other types of event, I wish they would say so.

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

                                @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


                                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

                                  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

                                          • Login

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