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. QListView in a QTabWidget tab - External Drop Not Working
Forum Updated to NodeBB v4.3 + New Features

QListView in a QTabWidget tab - External Drop Not Working

Scheduled Pinned Locked Moved Solved General and Desktop
19 Posts 5 Posters 1.3k Views 1 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #4

    Hi,

    The Model/View classes have already support for drag and drop. Therefore you have more specific methods to override in order to customise your model/view behaviour to your liking.

    See the dedicated chapter in Qt's documentation especially the mimeTypes, canDropMimeData and dropMimeData methods of your model class.

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    S 3 Replies Last reply
    1
    • SGaistS SGaist

      Hi,

      The Model/View classes have already support for drag and drop. Therefore you have more specific methods to override in order to customise your model/view behaviour to your liking.

      See the dedicated chapter in Qt's documentation especially the mimeTypes, canDropMimeData and dropMimeData methods of your model class.

      S Offline
      S Offline
      steveq
      wrote on last edited by
      #5

      @SGaist Thanks heaps for the heads up.
      I'll have a read of this and see how I go.

      1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        The Model/View classes have already support for drag and drop. Therefore you have more specific methods to override in order to customise your model/view behaviour to your liking.

        See the dedicated chapter in Qt's documentation especially the mimeTypes, canDropMimeData and dropMimeData methods of your model class.

        S Offline
        S Offline
        steveq
        wrote on last edited by steveq
        #6

        @SGaist Hi Again,
        I have read this documentation, and I'm still not sure how to proceed. I've modified my code to include this:

        	m_chatList->setAcceptDrops(true);
        	m_chatList->setDragEnabled(false);
        	m_chatList->setDropIndicatorShown(true);
        	m_chatList->viewport()->setAcceptDrops(true);
        	m_chatList->setDragDropMode(QAbstractItemView::DropOnly);
        

        But the SQListViewstill gives me the round circle with the line through it, indicating I can't drop.

        I'm sorry to be a pain, but could you please give me more of an idea of what to do?

        I'm obviously missing something here, but I just don't know what it is!

        Thanks so much,

        Steve Q.

        1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          The Model/View classes have already support for drag and drop. Therefore you have more specific methods to override in order to customise your model/view behaviour to your liking.

          See the dedicated chapter in Qt's documentation especially the mimeTypes, canDropMimeData and dropMimeData methods of your model class.

          S Offline
          S Offline
          steveq
          wrote on last edited by
          #7

          @SGaist I have managed to get drag and drop working on the entire widget, which will be fine for now.
          But I still can't get it to work on ONLY the listview in the widget.

          I have change my SQListView code to the following:

          sqlistview.cpp

          #include "sqlistview.h"
          
          #include <QDebug>
          #include <QDragEnterEvent>
          #include <QMimeData>
          
          SQListView::SQListView()
          {
          	viewport()->setAcceptDrops(true);
          }
          
          void SQListView::dropEvent(QDropEvent* e)
          {
          
          	foreach (const QUrl &url, e->mimeData()->urls())
          	{
          		 QString fileName = url.toLocalFile();
          		 qDebug() << "Dropped file:" << fileName;
          	}
          }
          
          void SQListView::dragEnterEvent(QDragEnterEvent *e)
          {
          	if (e->mimeData()->hasUrls())
          	{
          		e->acceptProposedAction();
          	}
          }
          

          sqlistview.h

          #ifndef SQLISTVIEW_H
          #define SQLISTVIEW_H
          
          #include <QObject>
          #include <QWidget>
          #include <QListView>
          
          class SQListView : public QListView
          {
          public:
          	SQListView();
          
          private slots:
          	void dragEnterEvent(QDragEnterEvent *e);
          	void dropEvent(QDropEvent *ev);
          
          protected:
          };
          
          #endif // SQLISTVIEW_H
          

          and in the creation of the listview:

          	m_chatList = new SQListView;
          
          	m_chatList->setResizeMode(QListView::Adjust);
          	m_chatList->setWordWrap(true);
          	m_chatList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
          	m_chatList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
          	m_chatList->setModel(&m_mymodel);
          	m_chatList->setMinimumSize(700,400);
          	m_chatList->setSelectionMode(QAbstractItemView::SingleSelection);
          
          	connect( m_chatList, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(chatListDoubleClicked(const QModelIndex &)));
          
          	// Capture context menu clicks...
          	m_chatList->setContextMenuPolicy(Qt::CustomContextMenu);
          
          	// ...and send those clicks to CustomMenuRequested
          	connect(m_chatList, SIGNAL(customContextMenuRequested(QPoint)), SLOT(ListMenuRequested(QPoint)));
          
          	// NOW tell the view to rely on our custom delegate for drawing
          	m_chatList->setItemDelegate(new ChatBubbleDelegate());
          

          But still no luck!

          Steve Q. :-)

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #8

            It's your model that you have to modify to support other mime types etc.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            S 1 Reply Last reply
            0
            • SGaistS SGaist

              It's your model that you have to modify to support other mime types etc.

              S Offline
              S Offline
              steveq
              wrote on last edited by
              #9

              @SGaist Ahhh okay. Thanks for the tip. Back to the docs it is for me!

              1 Reply Last reply
              0
              • S Offline
                S Offline
                steveq
                wrote on last edited by
                #10

                Hi all,

                I have now solved this.

                As my drop was not item dependent, that is I didn't care what was under the drop, so long as it was the list, I didn't need to subclass the QStandardItemModel. Instead I simply subclassed the QListView with the following overridden methods:

                	void dragEnterEvent(QDragEnterEvent *e);
                	void dropEvent(QDropEvent *ev);
                	void dragMoveEvent(QDragMoveEvent* event);
                

                I can now drop on my list and I will receive the filename of the file that was dropped. I then "emit" this filename to my parent to act on it accordingly.

                Thanks for all your help.

                Steve Q. :-)

                L 1 Reply Last reply
                0
                • S steveq

                  Hi all,

                  I have now solved this.

                  As my drop was not item dependent, that is I didn't care what was under the drop, so long as it was the list, I didn't need to subclass the QStandardItemModel. Instead I simply subclassed the QListView with the following overridden methods:

                  	void dragEnterEvent(QDragEnterEvent *e);
                  	void dropEvent(QDropEvent *ev);
                  	void dragMoveEvent(QDragMoveEvent* event);
                  

                  I can now drop on my list and I will receive the filename of the file that was dropped. I then "emit" this filename to my parent to act on it accordingly.

                  Thanks for all your help.

                  Steve Q. :-)

                  L Offline
                  L Offline
                  Luzz T
                  wrote on last edited by
                  #11

                  hi @steveq ,

                  I have encountered the same difficulties as you. then I follow your way : setAceeptDrop(true) and overridden methods

                  	void dragEnterEvent(QDragEnterEvent *e);
                  	void dropEvent(QDropEvent *ev);
                  	void dragMoveEvent(QDragMoveEvent* event);
                  

                  and add QDebug() in methods, but I don't see any output of console, and ListView still gives me the round circle with the line through it, indicating I can't drop. I'm obviously missing something here, but I just don't know what it is!

                  jsulmJ 1 Reply Last reply
                  0
                  • L Luzz T

                    hi @steveq ,

                    I have encountered the same difficulties as you. then I follow your way : setAceeptDrop(true) and overridden methods

                    	void dragEnterEvent(QDragEnterEvent *e);
                    	void dropEvent(QDropEvent *ev);
                    	void dragMoveEvent(QDragMoveEvent* event);
                    

                    and add QDebug() in methods, but I don't see any output of console, and ListView still gives me the round circle with the line through it, indicating I can't drop. I'm obviously missing something here, but I just don't know what it is!

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #12

                    @Luzz-T Please show the code of the class where overriding these methods and show how you're using this class.

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    L 1 Reply Last reply
                    1
                    • jsulmJ jsulm

                      @Luzz-T Please show the code of the class where overriding these methods and show how you're using this class.

                      L Offline
                      L Offline
                      Luzz T
                      wrote on last edited by
                      #13

                      @jsulm
                      I only want get file name by external drop. ListViewDrop class inherits QListView

                      ListViewDrop.h

                      #ifndef LISTVIEWDROP_H
                      #define LISTVIEWDROP_H
                      
                      #include <QListView>
                      
                      namespace Ui {
                      class ListViewDrop;
                      }
                      
                      class ListViewDrop : public QListView
                      {
                          Q_OBJECT
                      public:
                          explicit ListViewDrop(QWidget *parent = nullptr);
                          ~ListViewDrop();
                      
                      protected:
                          void dragEnterEvent(QDragEnterEvent* ev) override;
                          void dragMoveEvent(QDragMoveEvent *e) override;
                          void dropEvent(QDropEvent* ev) override;
                      };
                      
                      #endif // LISTVIEWDROP_H
                      

                      ListViewDrop.cpp

                      #include "listviewdrop.h"
                      #include <qdebug.h>
                      #include <QDragEnterEvent>
                      #include <QDropEvent>
                      #include <QMimeData>
                      #include <QUrl>
                      
                      ListViewDrop::ListViewDrop(QWidget* parent):
                          QListView(parent)
                      {
                          this->setAcceptDrops(true);
                      
                      }
                      
                      ListViewDrop::~ListViewDrop()
                      {
                      
                      }
                      
                      void ListViewDrop::dragEnterEvent(QDragEnterEvent *ev)
                      {
                          qDebug() << "ListViewDrop::dragEnterEvent";
                          if(ev->mimeData()->hasUrls())
                          {
                              ev->accept();
                          }
                          //ev->ignore();
                      }
                      
                      void ListViewDrop::dropEvent(QDropEvent *ev)
                      {
                          qDebug() << "ListViewDrop::dropEvent";
                          if(ev->mimeData()->hasUrls())
                          {
                              QList<QUrl> urls = ev->mimeData()->urls();
                      
                              for(int i=0; i<urls.size(); i++)
                              {
                                  qDebug() << urls.at(i).toLocalFile();
                              }
                          }
                      }
                      
                      void ListViewDrop::dragMoveEvent(QDragMoveEvent *e) {
                          qDebug() << "ListViewDrop::dragMoveEvent";
                      }
                      
                      

                      I create a ListViewDrop is in a QWidget

                      Thanks heaps in advance.

                      jsulmJ JonBJ 2 Replies Last reply
                      0
                      • L Luzz T

                        @jsulm
                        I only want get file name by external drop. ListViewDrop class inherits QListView

                        ListViewDrop.h

                        #ifndef LISTVIEWDROP_H
                        #define LISTVIEWDROP_H
                        
                        #include <QListView>
                        
                        namespace Ui {
                        class ListViewDrop;
                        }
                        
                        class ListViewDrop : public QListView
                        {
                            Q_OBJECT
                        public:
                            explicit ListViewDrop(QWidget *parent = nullptr);
                            ~ListViewDrop();
                        
                        protected:
                            void dragEnterEvent(QDragEnterEvent* ev) override;
                            void dragMoveEvent(QDragMoveEvent *e) override;
                            void dropEvent(QDropEvent* ev) override;
                        };
                        
                        #endif // LISTVIEWDROP_H
                        

                        ListViewDrop.cpp

                        #include "listviewdrop.h"
                        #include <qdebug.h>
                        #include <QDragEnterEvent>
                        #include <QDropEvent>
                        #include <QMimeData>
                        #include <QUrl>
                        
                        ListViewDrop::ListViewDrop(QWidget* parent):
                            QListView(parent)
                        {
                            this->setAcceptDrops(true);
                        
                        }
                        
                        ListViewDrop::~ListViewDrop()
                        {
                        
                        }
                        
                        void ListViewDrop::dragEnterEvent(QDragEnterEvent *ev)
                        {
                            qDebug() << "ListViewDrop::dragEnterEvent";
                            if(ev->mimeData()->hasUrls())
                            {
                                ev->accept();
                            }
                            //ev->ignore();
                        }
                        
                        void ListViewDrop::dropEvent(QDropEvent *ev)
                        {
                            qDebug() << "ListViewDrop::dropEvent";
                            if(ev->mimeData()->hasUrls())
                            {
                                QList<QUrl> urls = ev->mimeData()->urls();
                        
                                for(int i=0; i<urls.size(); i++)
                                {
                                    qDebug() << urls.at(i).toLocalFile();
                                }
                            }
                        }
                        
                        void ListViewDrop::dragMoveEvent(QDragMoveEvent *e) {
                            qDebug() << "ListViewDrop::dragMoveEvent";
                        }
                        
                        

                        I create a ListViewDrop is in a QWidget

                        Thanks heaps in advance.

                        jsulmJ Offline
                        jsulmJ Offline
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #14

                        @Luzz-T said in QListView in a QTabWidget tab - External Drop Not Working:

                        I create a ListViewDrop is in a QWidget

                        Please show how

                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                        L 1 Reply Last reply
                        1
                        • L Luzz T

                          @jsulm
                          I only want get file name by external drop. ListViewDrop class inherits QListView

                          ListViewDrop.h

                          #ifndef LISTVIEWDROP_H
                          #define LISTVIEWDROP_H
                          
                          #include <QListView>
                          
                          namespace Ui {
                          class ListViewDrop;
                          }
                          
                          class ListViewDrop : public QListView
                          {
                              Q_OBJECT
                          public:
                              explicit ListViewDrop(QWidget *parent = nullptr);
                              ~ListViewDrop();
                          
                          protected:
                              void dragEnterEvent(QDragEnterEvent* ev) override;
                              void dragMoveEvent(QDragMoveEvent *e) override;
                              void dropEvent(QDropEvent* ev) override;
                          };
                          
                          #endif // LISTVIEWDROP_H
                          

                          ListViewDrop.cpp

                          #include "listviewdrop.h"
                          #include <qdebug.h>
                          #include <QDragEnterEvent>
                          #include <QDropEvent>
                          #include <QMimeData>
                          #include <QUrl>
                          
                          ListViewDrop::ListViewDrop(QWidget* parent):
                              QListView(parent)
                          {
                              this->setAcceptDrops(true);
                          
                          }
                          
                          ListViewDrop::~ListViewDrop()
                          {
                          
                          }
                          
                          void ListViewDrop::dragEnterEvent(QDragEnterEvent *ev)
                          {
                              qDebug() << "ListViewDrop::dragEnterEvent";
                              if(ev->mimeData()->hasUrls())
                              {
                                  ev->accept();
                              }
                              //ev->ignore();
                          }
                          
                          void ListViewDrop::dropEvent(QDropEvent *ev)
                          {
                              qDebug() << "ListViewDrop::dropEvent";
                              if(ev->mimeData()->hasUrls())
                              {
                                  QList<QUrl> urls = ev->mimeData()->urls();
                          
                                  for(int i=0; i<urls.size(); i++)
                                  {
                                      qDebug() << urls.at(i).toLocalFile();
                                  }
                              }
                          }
                          
                          void ListViewDrop::dragMoveEvent(QDragMoveEvent *e) {
                              qDebug() << "ListViewDrop::dragMoveEvent";
                          }
                          
                          

                          I create a ListViewDrop is in a QWidget

                          Thanks heaps in advance.

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

                          @Luzz-T
                          First you must answer @jsulm's question.

                          But I see two possible issues in your current code, which may (or may not) need addressing after you have sorted out why your drag methods are not being hit at all:

                          • Your dragMoveEvent(QDragMoveEvent *e) does not accept the event. You need to have that as well as dragEnterEvent() accept the drag, else you are liable to end up with the "no drop" indicator. dropEvent should also accept it, I don't know if that matters in your case.

                          • In your dragEnterEvent you use ev->accept();. I'm not sure whether it matters, but here (and the other two methods) you are supposed to use acceptProposedAction().

                          L 1 Reply Last reply
                          0
                          • jsulmJ jsulm

                            @Luzz-T said in QListView in a QTabWidget tab - External Drop Not Working:

                            I create a ListViewDrop is in a QWidget

                            Please show how

                            L Offline
                            L Offline
                            Luzz T
                            wrote on last edited by
                            #16

                            @jsulm

                            "create" actually I use qt Designer, Layout following :
                            d4a95f13-7ed3-4d57-a8c2-f599b91dfd95-image.png

                            In the picture above ,the red box is the “ListViewDrop” of my promotion by QListView,and "SelectView" used in main.cpp

                            #include "selectview.h"
                            #include <QApplication>
                            
                            int main(int argc, char *argv[])
                            {
                                QApplication a(argc, argv);
                                SelectView w;
                                w.show();
                                return a.exec();
                            }
                            
                            
                            JonBJ 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @Luzz-T
                              First you must answer @jsulm's question.

                              But I see two possible issues in your current code, which may (or may not) need addressing after you have sorted out why your drag methods are not being hit at all:

                              • Your dragMoveEvent(QDragMoveEvent *e) does not accept the event. You need to have that as well as dragEnterEvent() accept the drag, else you are liable to end up with the "no drop" indicator. dropEvent should also accept it, I don't know if that matters in your case.

                              • In your dragEnterEvent you use ev->accept();. I'm not sure whether it matters, but here (and the other two methods) you are supposed to use acceptProposedAction().

                              L Offline
                              L Offline
                              Luzz T
                              wrote on last edited by
                              #17

                              @JonB

                              Thanks for the tip. This is a test code, which I will pay attention to in development

                              1 Reply Last reply
                              0
                              • L Luzz T

                                @jsulm

                                "create" actually I use qt Designer, Layout following :
                                d4a95f13-7ed3-4d57-a8c2-f599b91dfd95-image.png

                                In the picture above ,the red box is the “ListViewDrop” of my promotion by QListView,and "SelectView" used in main.cpp

                                #include "selectview.h"
                                #include <QApplication>
                                
                                int main(int argc, char *argv[])
                                {
                                    QApplication a(argc, argv);
                                    SelectView w;
                                    w.show();
                                    return a.exec();
                                }
                                
                                
                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by JonB
                                #18

                                @Luzz-T
                                In addition to my earlier points, you may need to add the following:

                                listView->setDropIndicatorShown(true);
                                

                                Also if your list view has a model look at what listView->model()->supportedDropActions() is returning. P.S. And also probably QAbstractItemModel::mimeTypes(), dropMimeData(), canDropMimeData() too --- in a word, are you using a model with your QListView?

                                I think you should implement your dragMoveEvent() now, as I found without that I got stick with a "no-entry" drop indicator all the time.

                                The important is to confirm whether any of your drag/drop overrides report a qDebug() output as their first line?

                                Finally, in Designer did you set any of the properties on your listView, there are several related to d&d?

                                L 1 Reply Last reply
                                0
                                • JonBJ JonB

                                  @Luzz-T
                                  In addition to my earlier points, you may need to add the following:

                                  listView->setDropIndicatorShown(true);
                                  

                                  Also if your list view has a model look at what listView->model()->supportedDropActions() is returning. P.S. And also probably QAbstractItemModel::mimeTypes(), dropMimeData(), canDropMimeData() too --- in a word, are you using a model with your QListView?

                                  I think you should implement your dragMoveEvent() now, as I found without that I got stick with a "no-entry" drop indicator all the time.

                                  The important is to confirm whether any of your drag/drop overrides report a qDebug() output as their first line?

                                  Finally, in Designer did you set any of the properties on your listView, there are several related to d&d?

                                  L Offline
                                  L Offline
                                  Luzz T
                                  wrote on last edited by Luzz T
                                  #19

                                  @JonB
                                  Thank you for your suggestions. I found the problem. The dragDropMode attribute is not set, it defaults to
                                  NoDragDrop . But strangely, the default attribute does not work in Windows, and the default value NoDragDrop is OK in MacOS,
                                  Also the version of QT may be different or for other reasons

                                  For all that It's already working. Thank all

                                  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