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. Drag and Drop between 3 QListViews
Forum Updated to NodeBB v4.3 + New Features

Drag and Drop between 3 QListViews

Scheduled Pinned Locked Moved General and Desktop
4 Posts 2 Posters 2.4k 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.
  • D Offline
    D Offline
    digga
    wrote on last edited by
    #1

    Hi all,

    I try to realize a drag and drop system between 3 QListViews, I thought about subclassing QAbstractListModel, each model inherits a QList<int>. I already searched around for solutions, but I didnt found any good example or explanation. What I already know is that I have to reimplement the functions in QAbstractListModel:

    • rowCount()
    • data()
    • setData()
    • headerData()

    About the following I am not sure

    • mimeTypes()
    • mimeData()
    • dropMimeData()
    • supportedDropActions()

    I think I also need a subclass of QListView and implement the following or don't I need to subclass ?

    • setAcceptDrops(true);
    • setDragEnabled(true);
    • setDragDropMode(QAbstractItemView::InternalMove);
    • setDropIndicatorShown(true);
    • setSelectionMode(QAbstractItemView::SingleSelection);
    • setDragDropMode(QAbstractItemView::DragDrop);

    My problem is I didnt found any implementation examples of any mime or drop method. Also the user shouldn't be able to drop a item outside of a QListView, if he does so it should drop back from where it came.
    Has anybody a good implementation for these methods?

    1 Reply Last reply
    0
    • M Offline
      M Offline
      marsupial
      wrote on last edited by
      #2

      I think this is a very good introduction into the topic: http://doc.qt.nokia.com/4.7-snapshot/model-view-programming.html#using-drag-and-drop-with-item-views

      Other than that, have a look at those examples on how to implement Drag and Drop:
      http://doc-snapshot.qt-project.org/4.8/examples-draganddrop.html

      How to subclass the actual model is being demontrated in multiple examples here: http://doc-snapshot.qt-project.org/4.8/examples-itemviews.html

      And last but not least, the documentation talks a little about mime-data in models: http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#mimeData

      1 Reply Last reply
      0
      • D Offline
        D Offline
        digga
        wrote on last edited by
        #3

        Ok, I read the articles you linked and implement the methods sofar. -But if I try to drag an item from one to another View it shows a crossed circle.-
        Edit: Ok i can drag things around, but I am not possible to drop them:(
        @ QList<int> list;
        list << 2;
        list << 4;
        list << 5;

        MODEL *model = new MODEL();
        model->setPlayers(list);
        ui->NotPossibleList->setModel(model);
        ui->NotPossibleList->setAcceptDrops(true);
        ui->NotPossibleList->setDragDropMode(QAbstractItemView::InternalMove);
        ui->NotPossibleList->setDropIndicatorShown(true);
        ui->NotPossibleList->setSelectionMode(QAbstractItemView::SingleSelection);
        ui->NotPossibleList->setDragEnabled(true);
        ui->NotPossibleList->viewport()->setAcceptDrops(true);
        ui->NotPossibleList->setDropIndicatorShown(true);
        ui->NotPossibleList->setDragDropMode(QAbstractItemView::DragDrop);
        
        MODEL *model2 = new MODEL();
        model2->setPlayers(QList<int>());
        ui->PresentList->setModel(model2);
        ui->PresentList->setAcceptDrops(true);
        ui->PresentList->setDragDropMode(QAbstractItemView::InternalMove);
        ui->PresentList->setDropIndicatorShown(true);
        ui->PresentList->setSelectionMode(QAbstractItemView::SingleSelection);
        ui->PresentList->setDragEnabled(true);
        ui->PresentList->viewport()->setAcceptDrops(true);
        ui->PresentList->setDropIndicatorShown(true);
        ui->PresentList->setDragDropMode(QAbstractItemView::DragDrop);@
        

        The implementation of the model.

        @#include "model.h"

        MODEL::MODEL()
        {
        manager = MANAGER::getInstance();
        }

        int MODEL::rowCount(const QModelIndex &parent) const
        {
        return parent.isValid() ? 0 : players.size();
        }

        QVariant MODEL::data(const QModelIndex &index, int role) const
        {
        if (!index.isValid() ||
        index.row() < 0 || index.row() >= players.size() ||
        index.column() < 0 || index.column() >= 1)
        return QVariant();

        if (role == Qt::DisplayRole && index.column() == 0)
        {
            return manager->getPlayer(players[index.row()])->name();
        }
        
        return QVariant();
        

        }

        bool MODEL::setData(const QModelIndex &index, const QVariant &value, int role)
        {
        if (!index.isValid() ||
        index.row() < 0 || index.row() >= players.size() ||
        index.column() < 0 || index.column() >= 1)
        return false;

        if (role == Qt::UserRole)
        {
            players.insert(index.row(), value.toInt());
        }
        
        emit dataChanged(index, index);
        return true;
        

        }

        QVariant MODEL::headerData(int section, Qt::Orientation orientation, int role) const
        {
        if (role != Qt::DisplayRole)
        return QVariant();

        if (orientation == Qt::Horizontal && section >= 1)
        {
            return tr("Player");
        }
        
        return QVariant();
        

        }

        Qt::ItemFlags MODEL::flags(const QModelIndex &index) const
        {
        Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;

        if (index.isValid())
            return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
        else
            return Qt::ItemIsDropEnabled | defaultFlags;
        

        }

        QStringList MODEL::mimeTypes()
        {
        QStringList types;
        types << "application/vnd.text.list";
        return types;
        }

        QMimeData* MODEL::mimeData(const QModelIndexList &indexes) const
        {
        QMimeData *mimeData = new QMimeData();
        QByteArray encodedData;

        QDataStream stream(&encodedData, QIODevice::WriteOnly);
        
        foreach (const QModelIndex &index, indexes) {
            if (index.isValid())
            {
                QString text = data(index, Qt::UserRole).toString();
                stream << text;
            }
        }
        
        mimeData->setData("application/vnd.text.list", encodedData);
        return mimeData;
        

        }

        bool MODEL::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
        {
        if (action == Qt::IgnoreAction)
        return true;

        if (!data->hasFormat("application/vnd.text.list"))
            return false;
        
        if (column > 0)
            return false;
        
        int beginRow;
        
        if (row != -1)
            beginRow = row;
        else if (parent.isValid())
            beginRow = parent.row();
        else
            beginRow = rowCount(QModelIndex());
        
        QByteArray encodedData = data->data("application/vnd.text.list");
        QDataStream stream(&encodedData, QIODevice::ReadOnly);
        QStringList newItems;
        int rows = 0;
        
        while (!stream.atEnd())
        {
            QString text;
            stream >> text;
            newItems << text;
            ++rows;
        }
        
        insertRows(beginRow, rows, QModelIndex());
        foreach (const QString &text, newItems)
        {
            QModelIndex idx = index(beginRow, 0, QModelIndex());
            setData(idx, text, Qt::UserRole);
            beginRow++;
        }
        
        return true;
        

        }

        Qt::DropActions MODEL::supportedDropActions()
        {
        return Qt::CopyAction | Qt::MoveAction;
        }

        void MODEL::setPlayers(QList<int> players)
        {
        this->players = players;
        }

        QList<int> MODEL::getPlayers()
        {
        return players;
        }
        @

        Is there any thing which I forgot to implement or failed to implement?

        1 Reply Last reply
        0
        • D Offline
          D Offline
          digga
          wrote on last edited by
          #4

          Sorry, that I have to push it up again, but I am still stuck at this problem. My actual code looks like this:
          @

          MODEL::MODEL()
          {
          manager = MANAGER::getInstance();
          }

          int MODEL::rowCount(const QModelIndex &parent) const
          {
          return parent.isValid() ? 0 : list.size();
          }

          QVariant MODEL::data(const QModelIndex &index, int role) const
          {
          if (!index.isValid() ||
          index.row() < 0 || index.row() >= list.size() ||
          index.column() < 0 || index.column() >= 1)
          return QVariant();

          if (role == Qt::DisplayRole && index.column() == 0)
          {
              return manager->findEntry(list[index.row()])->getName();
          }
          
          return QVariant();
          

          }

          bool MODEL::setData(const QModelIndex &index, const QVariant &value, int role)
          {
          if (!index.isValid() ||
          index.row() < 0 || index.row() >= list.size() ||
          index.column() < 0 || index.column() >= 1)
          return false;

          if (role == Qt::UserRole)
          {
              list[index.row()] = value.toInt();
          }
          
          emit dataChanged(index, index);
          return true;
          

          }

          QVariant MODEL::headerData(int section, Qt::Orientation orientation, int role) const
          {

          return QVariant();
          

          }

          bool MODEL::insertRows(int row, int count, const QModelIndex &parent)
          {
          beginInsertRows(QModelIndex(), row, row + count - 1);

          for (int i = 0; i < count; i++)
          {
              list.insert(row, -1);
          }
          
          endInsertRows();
          return true;
          

          }

          bool MODEL::removeRows(int row, int count, const QModelIndex &parent)
          {
          beginRemoveRows(QModelIndex(), row, row + count - 1);

          for (int i = 0; i < count; i++)
          {
              list.removeAt(row);
          }
          
          endRemoveRows();
          return true;
          

          }

          Qt::ItemFlags MODEL::flags(const QModelIndex &index) const
          {
          Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;

          if (index.isValid())
              return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
          else
              return Qt::ItemIsDropEnabled | defaultFlags;
          

          }

          QStringList MODEL::mimeTypes()
          {
          QStringList types;
          types << "application/vnd.text.list";
          return types;
          }

          QMimeData* MODEL::mimeData(const QModelIndexList &indexes) const
          {
          QMimeData *mimeData = new QMimeData();
          QByteArray encodedData;

          QDataStream stream(&encodedData, QIODevice::WriteOnly);
          
          foreach (const QModelIndex &index, indexes) {
              if (index.isValid())
              {
                  QString text = data(index, Qt::DisplayRole).toString();
                  stream << text;
              }
          }
          
          mimeData->setData("application/vnd.text.list", encodedData);
          return mimeData;
          

          }

          bool MODEL::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
          {
          if (action == Qt::IgnoreAction)
          return true;

          if (!data->hasFormat("application/vnd.text.list"))
              return false;
          
          if (column > 0)
              return false;
          
          int beginRow;
          
          if (row != -1)
              beginRow = row;
          else if (parent.isValid())
              beginRow = parent.row();
          else
              beginRow = rowCount(QModelIndex());
          
          QByteArray encodedData = data->data("application/vnd.text.list");
          QDataStream stream(&encodedData, QIODevice::ReadOnly);
          QStringList newItems;
          int rows = 0;
          
          while (!stream.atEnd())
          {
              QString text;
              stream >> text;
              newItems << text;
              ++rows;
          }
          
          insertRows(beginRow, rows, QModelIndex());
          foreach (const QString &text, newItems)
          {
              QModelIndex idx = index(beginRow, 0, QModelIndex());
              setData(idx, text, Qt::UserRole);
              beginRow++;
          }
          
          return true;
          

          }

          Qt::DropActions MODEL::supportedDropActions() const
          {
          return Qt::MoveAction;
          }

          void MODEL::setList(QList<int> list)
          {
          this->list = list;
          }

          QList<int> MODEL::getList()
          {
          return list;
          }
          @

          In my mainwindow.cpp
          @ MODEL*model = new MODEL();
          model->setPlayers(list);
          ui->NotPossibleList->setModel(model);
          ui->NotPossibleList->setSelectionMode(QAbstractItemView::ExtendedSelection);
          ui->NotPossibleList->setDragEnabled(true);
          ui->NotPossibleList->setAcceptDrops(true);
          ui->NotPossibleList->setDropIndicatorShown(true);
          @

          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