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. QTreeView how to support move action?
Forum Updated to NodeBB v4.3 + New Features

QTreeView how to support move action?

Scheduled Pinned Locked Moved Unsolved General and Desktop
17 Posts 6 Posters 1.3k Views 4 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.
  • M mpergand

    @StudentScripter
    Here the code I 've used in a bookmarks treeview for a web browser:

    QMimeData* mimeData(const QModelIndexList &indexes) const
    				{
                    if(indexes.isEmpty()) return NULL;
    
    				QMimeData* mime = new QMimeData;
                    QByteArray bytes;
    				QDataStream stream(&bytes,QIODevice::WriteOnly);
    
    				QModelIndex index=indexes.first();	// supporte seulement un élément
    				if(index.isValid())
    					{
    					QString text=data(index, Qt::DisplayRole).toString();
    					stream<<index.internalId()<<index.row()<<index.column()<<text;
    					}
    
                    mime->setData(MIME_Bookmark,bytes);
    				return mime;
    				}
    
    	QStringList mimeTypes() const
    				{
    				QStringList list;
                    list<<"text/uri-list"<<"text/plain"<<MIME_Bookmark;
    				return list;
    				}
    
    		bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
    				{ Q_UNUSED(column)
    				if(action EQ Qt::IgnoreAction) return false;
    
                    if(action EQ Qt::MoveAction)
                        {
                        QByteArray bytes=data->data(MIME_Bookmark);
                        QDataStream stream(&bytes,QIODevice::QIODevice::ReadOnly);
                        qintptr i; int r,c; QString text;
                        stream>>i>>r>>c>>text;
                        QModelIndex index=createIndex(r,c,i);
    
                        moveRow(index,index.row(),parent,row);
                        }
    
                    EventCenter().postEvent(Event_BookmarksChanged,this);
    
    				return true;
    				}
    
    Qt::DropActions supportedDragActions() const
    				{
                    return Qt::MoveAction;//|Qt::CopyAction;
    				}
    
    Qt::DropActions supportedDropActions() const
                    {
                    return Qt::LinkAction|Qt::MoveAction|Qt::CopyAction;
                    }
    
    
    S Offline
    S Offline
    StudentScripter
    wrote on last edited by
    #8

    @mpergand Sorry for asking again but i got stuck eventually and haven't found any solution on the web. I want to support dragging and dropping between the rows, but everytime i try this my action gets prevented. How can i override that behaviour?

    6b62e548-92e4-4cb7-867c-09a78fc34ff8-image.png

    I have overwritten the dropindicator in my treeview:

    
    void ViewLayerList::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
    {
    
    
        if (selectionModel()->isSelected(index)) {
        
        // Zeichnen Sie den Einzugsbereich (Indentation) mit Ihrer gewünschten Farbe
                
                painter->fillRect(options.rect, QColor(173, 216, 230)); // "lightblue" Hervorhebungsfarbe*/
                
           
            
        }
        
        
        
    
        
        QTreeView::drawRow(painter, options, index); // Rufen Sie die Basisimplementierung auf, um die Standardzeichnung durchzuführen
        
        
        
    
    if(MouseIsPressed == true)
    {
    
    // Überprüfen Sie die Position des Drop-Indikators
        QAbstractItemView::DropIndicatorPosition position = dropIndicatorPosition();
    
        // Überprüfen Sie, ob das aktuelle Element das Element ist, über dem sich die Maus befindet
        QModelIndex mouseIndex = indexAt(mapFromGlobal(QCursor::pos()));
        if (mouseIndex == index) {
            // Speichern Sie den ursprünglichen Stift
            QPen originalPen = painter->pen();
            QPen IndicatorPen;
    
            // Bestimmen Sie das Aussehen des Drop-Indikators basierend auf seiner Position
            switch (position) {
                case QAbstractItemView::AboveItem:
                case QAbstractItemView::BelowItem:
                    
                    IndicatorPen.setWidth(9);  // Setzen Sie die Breite des Stifts
                    IndicatorPen.setColor(QColor(0, 255, 0, 127));  // Setzen Sie die Farbe des Stifts auf halbtransparentes Grün
                    painter->setPen(IndicatorPen);
                    painter->drawLine(options.rect.topLeft(), options.rect.topRight());
                    break;
                case QAbstractItemView::OnItem:
                    break;
            
                    
                case QAbstractItemView::OnViewport:
                    break;
            }
    
            // Stellen Sie den ursprünglichen Stift wieder her
            painter->setPen(originalPen);
        }
    }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    void ViewLayerList::dragEnterEvent(QDragEnterEvent *event)
    {
    
                
        QTreeView::dragEnterEvent(event);
    }
    
    
    
    
    void ViewLayerList::dragMoveEvent(QDragMoveEvent *event)
    {
    
    QModelIndex belowIndex;
    
        // Überprüfen Sie die Position des Drop-Indikators
        QAbstractItemView::DropIndicatorPosition position = dropIndicatorPosition();
    
        // Bestimmen Sie das Aussehen des Drop-Indikators basierend auf seiner Position
        switch (position) {
            case QAbstractItemView::AboveItem:
            case QAbstractItemView::BelowItem:
                qDebug() << "Drop AboveItem or BelowItem";
                DropOnItem = false;
    
                // Holen Sie sich den QModelIndex des Elements unterhalb der aktuellen Position
                belowIndex = indexAt(event->position().toPoint() + QPoint(0, 1));
                if (belowIndex.isValid()) {
                    // Holen Sie sich die Zeile des Elements
                    RowBelowDropPositon = belowIndex.row();
                    qDebug() << "Row of item below: " << RowBelowDropPositon;
                }
    
                break;
            case QAbstractItemView::OnItem:
                qDebug() << "Drop OnItem";
                DropOnItem = true;
                break;
            case QAbstractItemView::OnViewport:
                qDebug() << "Drop OnViewport";
                
                break;
        }
    
        QTreeView::dragMoveEvent(event);
    }
    
    
    

    I also added the appropriate flags in my model:

    #include "ViewLayerStandartItemModel.h"
    #include "ViewLayerList.h"
    #include <QMimeData>
    #include <QDataStream>
    
    ViewLayerStandartItemModel::ViewLayerStandartItemModel(int rows, int columns, QObject *parent)
        : QStandardItemModel(rows, columns, parent)
    {
    
    }
    
    
    
    
    
    Qt::ItemFlags ViewLayerStandartItemModel::flags(const QModelIndex &index) const {
        Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index);
    
        // Überprüfen Sie, ob der Index zu einem Ihrer speziellen Delegaten gehört
        if (!data(index, CanHaveChildrenRole).toBool()) {
            return (defaultFlags & ~Qt::ItemIsDropEnabled) | Qt::ItemIsDragEnabled; // Entfernen Sie das ItemIsDropEnabled-Flag und fügen Sie das ItemIsDragEnabled-Flag hinzu
        }
    
    
    
    
        return defaultFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; // Fügen Sie das ItemIsDragEnabled und ItemIsDropEnabled Flag hinzu
    }
    
    
    
    
    
    
    
    
    Qt::DropActions ViewLayerStandartItemModel::supportedDragActions() const
    {
        return Qt::MoveAction | Qt::CopyAction;
    }
    
    
    
    Qt::DropActions ViewLayerStandartItemModel::supportedDropActions() const
    {
        return Qt::MoveAction | Qt::CopyAction;
    }
    
    
    
    
    
    
    
    
    QStringList ViewLayerStandartItemModel::mimeTypes() const
    {
      QStringList list;
        list << "application/production"; // Ändern Sie den MIME-Typ nach Bedarf
        return list;
       
    }
    
    
    
    QMimeData *ViewLayerStandartItemModel::mimeData(const QModelIndexList &indexes) const
    {
         if(indexes.isEmpty()) return NULL;
         
    QMimeData *mimeData = new QMimeData;
        QByteArray encodedData;
    
        // Hier kannst du die Daten für das Drag-and-Drop speichern.
        // In diesem Beispiel codieren wir die Zeilen- und Spaltenindizes.
        QDataStream stream(&encodedData, QIODevice::WriteOnly);
        for (const QModelIndex &index : indexes) {
            if (index.isValid()) {
                int row = index.row();
                int column = index.column();
                stream << row << column;
            }
        }
    
        mimeData->setData("application/production", encodedData);
        return mimeData;
    }
    
    
    
    
    
    
    bool ViewLayerStandartItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
    {
    
    
        if (!data || !data->hasFormat("application/production")) {
            qDebug() << "Wrong Data";
            return false;
        }
    
        QByteArray encodedData = data->data("application/production");
        QDataStream stream(&encodedData, QIODevice::ReadOnly);
    
        if (parent.isValid()) {
            // Wenn parent gültig ist, füge das Item als Kind des Parent-Items ein.
            while (!stream.atEnd()) {
                int sourceRow, sourceColumn;
                stream >> sourceRow >> sourceColumn;
                
                qDebug() << "SourceRow: " << sourceRow;
                
                
                
                
                if (row > parent.row()) {
                    qDebug() << "Dropped below item at row: " << parent.row();
                    // Handle the drop below the parent item.
                } else if (row < parent.row()) {
                    qDebug() << "Dropped above item at row: " << parent.row();
                    // Handle the drop above the parent item.
                } else {
                    qDebug() << "Dropped on item at row: " << parent.row();
                    // Handle the drop on the parent item.
                }
                
                // You can also check the `column` value to determine the drop position in columns if needed.
            }
            
            return true; // Return true if the data was successfully processed.
        }
    
        // If parent is not valid, it means the item is dropped on an empty space in the view.
        qDebug() << "Dropped in empty space at row: " << row;
      
    
        return true; // Return true, wenn die Daten erfolgreich verarbeitet wurden.
    }
    
    
    S 1 Reply Last reply
    0
    • S StudentScripter

      @mpergand Sorry for asking again but i got stuck eventually and haven't found any solution on the web. I want to support dragging and dropping between the rows, but everytime i try this my action gets prevented. How can i override that behaviour?

      6b62e548-92e4-4cb7-867c-09a78fc34ff8-image.png

      I have overwritten the dropindicator in my treeview:

      
      void ViewLayerList::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
      {
      
      
          if (selectionModel()->isSelected(index)) {
          
          // Zeichnen Sie den Einzugsbereich (Indentation) mit Ihrer gewünschten Farbe
                  
                  painter->fillRect(options.rect, QColor(173, 216, 230)); // "lightblue" Hervorhebungsfarbe*/
                  
             
              
          }
          
          
          
      
          
          QTreeView::drawRow(painter, options, index); // Rufen Sie die Basisimplementierung auf, um die Standardzeichnung durchzuführen
          
          
          
      
      if(MouseIsPressed == true)
      {
      
      // Überprüfen Sie die Position des Drop-Indikators
          QAbstractItemView::DropIndicatorPosition position = dropIndicatorPosition();
      
          // Überprüfen Sie, ob das aktuelle Element das Element ist, über dem sich die Maus befindet
          QModelIndex mouseIndex = indexAt(mapFromGlobal(QCursor::pos()));
          if (mouseIndex == index) {
              // Speichern Sie den ursprünglichen Stift
              QPen originalPen = painter->pen();
              QPen IndicatorPen;
      
              // Bestimmen Sie das Aussehen des Drop-Indikators basierend auf seiner Position
              switch (position) {
                  case QAbstractItemView::AboveItem:
                  case QAbstractItemView::BelowItem:
                      
                      IndicatorPen.setWidth(9);  // Setzen Sie die Breite des Stifts
                      IndicatorPen.setColor(QColor(0, 255, 0, 127));  // Setzen Sie die Farbe des Stifts auf halbtransparentes Grün
                      painter->setPen(IndicatorPen);
                      painter->drawLine(options.rect.topLeft(), options.rect.topRight());
                      break;
                  case QAbstractItemView::OnItem:
                      break;
              
                      
                  case QAbstractItemView::OnViewport:
                      break;
              }
      
              // Stellen Sie den ursprünglichen Stift wieder her
              painter->setPen(originalPen);
          }
      }
      }
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      void ViewLayerList::dragEnterEvent(QDragEnterEvent *event)
      {
      
                  
          QTreeView::dragEnterEvent(event);
      }
      
      
      
      
      void ViewLayerList::dragMoveEvent(QDragMoveEvent *event)
      {
      
      QModelIndex belowIndex;
      
          // Überprüfen Sie die Position des Drop-Indikators
          QAbstractItemView::DropIndicatorPosition position = dropIndicatorPosition();
      
          // Bestimmen Sie das Aussehen des Drop-Indikators basierend auf seiner Position
          switch (position) {
              case QAbstractItemView::AboveItem:
              case QAbstractItemView::BelowItem:
                  qDebug() << "Drop AboveItem or BelowItem";
                  DropOnItem = false;
      
                  // Holen Sie sich den QModelIndex des Elements unterhalb der aktuellen Position
                  belowIndex = indexAt(event->position().toPoint() + QPoint(0, 1));
                  if (belowIndex.isValid()) {
                      // Holen Sie sich die Zeile des Elements
                      RowBelowDropPositon = belowIndex.row();
                      qDebug() << "Row of item below: " << RowBelowDropPositon;
                  }
      
                  break;
              case QAbstractItemView::OnItem:
                  qDebug() << "Drop OnItem";
                  DropOnItem = true;
                  break;
              case QAbstractItemView::OnViewport:
                  qDebug() << "Drop OnViewport";
                  
                  break;
          }
      
          QTreeView::dragMoveEvent(event);
      }
      
      
      

      I also added the appropriate flags in my model:

      #include "ViewLayerStandartItemModel.h"
      #include "ViewLayerList.h"
      #include <QMimeData>
      #include <QDataStream>
      
      ViewLayerStandartItemModel::ViewLayerStandartItemModel(int rows, int columns, QObject *parent)
          : QStandardItemModel(rows, columns, parent)
      {
      
      }
      
      
      
      
      
      Qt::ItemFlags ViewLayerStandartItemModel::flags(const QModelIndex &index) const {
          Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index);
      
          // Überprüfen Sie, ob der Index zu einem Ihrer speziellen Delegaten gehört
          if (!data(index, CanHaveChildrenRole).toBool()) {
              return (defaultFlags & ~Qt::ItemIsDropEnabled) | Qt::ItemIsDragEnabled; // Entfernen Sie das ItemIsDropEnabled-Flag und fügen Sie das ItemIsDragEnabled-Flag hinzu
          }
      
      
      
      
          return defaultFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; // Fügen Sie das ItemIsDragEnabled und ItemIsDropEnabled Flag hinzu
      }
      
      
      
      
      
      
      
      
      Qt::DropActions ViewLayerStandartItemModel::supportedDragActions() const
      {
          return Qt::MoveAction | Qt::CopyAction;
      }
      
      
      
      Qt::DropActions ViewLayerStandartItemModel::supportedDropActions() const
      {
          return Qt::MoveAction | Qt::CopyAction;
      }
      
      
      
      
      
      
      
      
      QStringList ViewLayerStandartItemModel::mimeTypes() const
      {
        QStringList list;
          list << "application/production"; // Ändern Sie den MIME-Typ nach Bedarf
          return list;
         
      }
      
      
      
      QMimeData *ViewLayerStandartItemModel::mimeData(const QModelIndexList &indexes) const
      {
           if(indexes.isEmpty()) return NULL;
           
      QMimeData *mimeData = new QMimeData;
          QByteArray encodedData;
      
          // Hier kannst du die Daten für das Drag-and-Drop speichern.
          // In diesem Beispiel codieren wir die Zeilen- und Spaltenindizes.
          QDataStream stream(&encodedData, QIODevice::WriteOnly);
          for (const QModelIndex &index : indexes) {
              if (index.isValid()) {
                  int row = index.row();
                  int column = index.column();
                  stream << row << column;
              }
          }
      
          mimeData->setData("application/production", encodedData);
          return mimeData;
      }
      
      
      
      
      
      
      bool ViewLayerStandartItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
      {
      
      
          if (!data || !data->hasFormat("application/production")) {
              qDebug() << "Wrong Data";
              return false;
          }
      
          QByteArray encodedData = data->data("application/production");
          QDataStream stream(&encodedData, QIODevice::ReadOnly);
      
          if (parent.isValid()) {
              // Wenn parent gültig ist, füge das Item als Kind des Parent-Items ein.
              while (!stream.atEnd()) {
                  int sourceRow, sourceColumn;
                  stream >> sourceRow >> sourceColumn;
                  
                  qDebug() << "SourceRow: " << sourceRow;
                  
                  
                  
                  
                  if (row > parent.row()) {
                      qDebug() << "Dropped below item at row: " << parent.row();
                      // Handle the drop below the parent item.
                  } else if (row < parent.row()) {
                      qDebug() << "Dropped above item at row: " << parent.row();
                      // Handle the drop above the parent item.
                  } else {
                      qDebug() << "Dropped on item at row: " << parent.row();
                      // Handle the drop on the parent item.
                  }
                  
                  // You can also check the `column` value to determine the drop position in columns if needed.
              }
              
              return true; // Return true if the data was successfully processed.
          }
      
          // If parent is not valid, it means the item is dropped on an empty space in the view.
          qDebug() << "Dropped in empty space at row: " << row;
        
      
          return true; // Return true, wenn die Daten erfolgreich verarbeitet wurden.
      }
      
      
      S Offline
      S Offline
      StudentScripter
      wrote on last edited by
      #9

      @StudentScripter Yeahhh i found the solution, i simply had to acceptProposedAction in the dragMoveEvent. :)

      S 1 Reply Last reply
      0
      • S StudentScripter

        @StudentScripter Yeahhh i found the solution, i simply had to acceptProposedAction in the dragMoveEvent. :)

        S Offline
        S Offline
        StudentScripter
        wrote on last edited by
        #10

        @mpergand @SGaist

        So i tried implementing all the methods and im able to drag and drop onto other items aswell as between the rows, but sadly in all those cases the dropped items just disappear, they just vanish. Why what could i do to fix this?

        I want to support the reordering aswell as making items children of others by drag and drop.

        Here is the code inside my standartitemmodel:

        #include "ViewLayerStandartItemModel.h"
        #include "ViewLayerList.h"
        #include <QMimeData>
        #include <QDataStream>
        
        ViewLayerStandartItemModel::ViewLayerStandartItemModel(int rows, int columns, QObject *parent)
            : QStandardItemModel(rows, columns, parent)
        {
        
        }
        
        
        
        
        
        Qt::ItemFlags ViewLayerStandartItemModel::flags(const QModelIndex &index) const {
            Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index);
        
            // Überprüfen Sie, ob der Index zu einem Ihrer speziellen Delegaten gehört
            if (!data(index, CanHaveChildrenRole).toBool()) {
                return (defaultFlags & ~Qt::ItemIsDropEnabled) | Qt::ItemIsDragEnabled; // Entfernen Sie das ItemIsDropEnabled-Flag und fügen Sie das ItemIsDragEnabled-Flag hinzu
            }
        
        
        
        
            return defaultFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; // Fügen Sie das ItemIsDragEnabled und ItemIsDropEnabled Flag hinzu
        }
        
        
        
        
        
        
        
        
        Qt::DropActions ViewLayerStandartItemModel::supportedDragActions() const
        {
            return Qt::MoveAction | Qt::CopyAction;
        }
        
        
        
        Qt::DropActions ViewLayerStandartItemModel::supportedDropActions() const
        {
            return Qt::MoveAction | Qt::CopyAction;
        }
        
        
        
        
        
        
        
        
        QStringList ViewLayerStandartItemModel::mimeTypes() const
        {
          QStringList list;
            list << "application/production"; // Ändern Sie den MIME-Typ nach Bedarf
            return list;
           
        }
        
        
        
        QMimeData *ViewLayerStandartItemModel::mimeData(const QModelIndexList &indexes) const
        {
             if(indexes.isEmpty()) return NULL;
             
        QMimeData *mimeData = new QMimeData;
            QByteArray encodedData;
        
            // Hier kannst du die Daten für das Drag-and-Drop speichern.
            // In diesem Beispiel codieren wir die Zeilen- und Spaltenindizes.
            QDataStream stream(&encodedData, QIODevice::WriteOnly);
            for (const QModelIndex &index : indexes) {
                if (index.isValid()) {
                    int row = index.row();
                    int column = index.column();
                    stream << row << column;
                }
            }
        
            mimeData->setData("application/production", encodedData);
            return mimeData;
        }
        
        
        
        
        
        
        
        bool ViewLayerStandartItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
        {
        
        
        
            
            
              
                
        
            if (!data || !data->hasFormat("application/production")) {
                qDebug() << "Wrong Data";
                return false;
            }
        
            QByteArray encodedData = data->data("application/production");
            QDataStream stream(&encodedData, QIODevice::ReadOnly);
        
        
        
        
            qDebug()<< "Wird gecalled";
            
                    while (!stream.atEnd()) {
                    int sourceRow, sourceColumn;
        
                    stream >> sourceRow >> sourceColumn;
                    
        
                     // Get the item that was dragged
                QStandardItem *item = this->item(sourceRow, sourceColumn);
        
                // Remove the item from its original position
                this->takeRow(sourceRow);
        
                // Insert the item at the new position
                this->insertRow(row, item);
            
                      
                
                    }
            
            
            return true; // Return true if the data was successfully processed.  
        }
        
        
        
        
        SGaistS 1 Reply Last reply
        0
        • S StudentScripter

          @mpergand @SGaist

          So i tried implementing all the methods and im able to drag and drop onto other items aswell as between the rows, but sadly in all those cases the dropped items just disappear, they just vanish. Why what could i do to fix this?

          I want to support the reordering aswell as making items children of others by drag and drop.

          Here is the code inside my standartitemmodel:

          #include "ViewLayerStandartItemModel.h"
          #include "ViewLayerList.h"
          #include <QMimeData>
          #include <QDataStream>
          
          ViewLayerStandartItemModel::ViewLayerStandartItemModel(int rows, int columns, QObject *parent)
              : QStandardItemModel(rows, columns, parent)
          {
          
          }
          
          
          
          
          
          Qt::ItemFlags ViewLayerStandartItemModel::flags(const QModelIndex &index) const {
              Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index);
          
              // Überprüfen Sie, ob der Index zu einem Ihrer speziellen Delegaten gehört
              if (!data(index, CanHaveChildrenRole).toBool()) {
                  return (defaultFlags & ~Qt::ItemIsDropEnabled) | Qt::ItemIsDragEnabled; // Entfernen Sie das ItemIsDropEnabled-Flag und fügen Sie das ItemIsDragEnabled-Flag hinzu
              }
          
          
          
          
              return defaultFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; // Fügen Sie das ItemIsDragEnabled und ItemIsDropEnabled Flag hinzu
          }
          
          
          
          
          
          
          
          
          Qt::DropActions ViewLayerStandartItemModel::supportedDragActions() const
          {
              return Qt::MoveAction | Qt::CopyAction;
          }
          
          
          
          Qt::DropActions ViewLayerStandartItemModel::supportedDropActions() const
          {
              return Qt::MoveAction | Qt::CopyAction;
          }
          
          
          
          
          
          
          
          
          QStringList ViewLayerStandartItemModel::mimeTypes() const
          {
            QStringList list;
              list << "application/production"; // Ändern Sie den MIME-Typ nach Bedarf
              return list;
             
          }
          
          
          
          QMimeData *ViewLayerStandartItemModel::mimeData(const QModelIndexList &indexes) const
          {
               if(indexes.isEmpty()) return NULL;
               
          QMimeData *mimeData = new QMimeData;
              QByteArray encodedData;
          
              // Hier kannst du die Daten für das Drag-and-Drop speichern.
              // In diesem Beispiel codieren wir die Zeilen- und Spaltenindizes.
              QDataStream stream(&encodedData, QIODevice::WriteOnly);
              for (const QModelIndex &index : indexes) {
                  if (index.isValid()) {
                      int row = index.row();
                      int column = index.column();
                      stream << row << column;
                  }
              }
          
              mimeData->setData("application/production", encodedData);
              return mimeData;
          }
          
          
          
          
          
          
          
          bool ViewLayerStandartItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
          {
          
          
          
              
              
                
                  
          
              if (!data || !data->hasFormat("application/production")) {
                  qDebug() << "Wrong Data";
                  return false;
              }
          
              QByteArray encodedData = data->data("application/production");
              QDataStream stream(&encodedData, QIODevice::ReadOnly);
          
          
          
          
              qDebug()<< "Wird gecalled";
              
                      while (!stream.atEnd()) {
                      int sourceRow, sourceColumn;
          
                      stream >> sourceRow >> sourceColumn;
                      
          
                       // Get the item that was dragged
                  QStandardItem *item = this->item(sourceRow, sourceColumn);
          
                  // Remove the item from its original position
                  this->takeRow(sourceRow);
          
                  // Insert the item at the new position
                  this->insertRow(row, item);
              
                        
                  
                      }
              
              
              return true; // Return true if the data was successfully processed.  
          }
          
          
          
          
          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #11

          @StudentScripter takeRow removes a complete row of items, is that really what you want ?

          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

            @StudentScripter takeRow removes a complete row of items, is that really what you want ?

            S Offline
            S Offline
            StudentScripter
            wrote on last edited by
            #12

            @SGaist I only have 1 column so yes removing the entire row and reinserting it at the dropped postion should be fine. However the drop doesn't seem to work right. When i drop one item onto another the dropped item disapears but i do not get the usual dropdown arrow on the item that should be the new parent.

            JonBJ 1 Reply Last reply
            0
            • S Offline
              S Offline
              SamiV123
              wrote on last edited by
              #13

              I've given up on the QTreeView a long time ago.

              It's just rocket science to me and I really doubt the way it interacts the model is the simplest that it could be. It seems to be full of complications...

              I found it's easier for me to write my own tree (view) widget that fits my use case than try to figure out the QTreeView.

              In case you want to go this route here's my code (GPL 3.0)

              https://github.com/ensisoft/detonator/blob/master/editor/gui/treewidget.cpp

              1 Reply Last reply
              1
              • S StudentScripter

                @SGaist I only have 1 column so yes removing the entire row and reinserting it at the dropped postion should be fine. However the drop doesn't seem to work right. When i drop one item onto another the dropped item disapears but i do not get the usual dropdown arrow on the item that should be the new parent.

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

                @StudentScripter
                I have not used QTreeView much or done drag and drop, but in your code I do not see anything which re-parents the moved item to whatever item it is dropped onto. Don't you have to do that?

                        // Insert the item at the new position
                        this->insertRow(row, item);
                

                Do you not need to use something like bool QStandardItemModel::insertRow(int row, const QModelIndex &parent = QModelIndex()) to pass new parent?

                Additionally/separately. The row you are passing here is the original one passed to dropMimeData(). However, you have preceded that with this->takeRow(sourceRow);. That deletes the sourceRow row. Depending on where you drag from-to, do you have to be careful to maybe alter the value of row if sourceRow came before it/is less than it? Perhaps only when they have the same parent, I don't know.

                S 1 Reply Last reply
                0
                • JonBJ JonB

                  @StudentScripter
                  I have not used QTreeView much or done drag and drop, but in your code I do not see anything which re-parents the moved item to whatever item it is dropped onto. Don't you have to do that?

                          // Insert the item at the new position
                          this->insertRow(row, item);
                  

                  Do you not need to use something like bool QStandardItemModel::insertRow(int row, const QModelIndex &parent = QModelIndex()) to pass new parent?

                  Additionally/separately. The row you are passing here is the original one passed to dropMimeData(). However, you have preceded that with this->takeRow(sourceRow);. That deletes the sourceRow row. Depending on where you drag from-to, do you have to be careful to maybe alter the value of row if sourceRow came before it/is less than it? Perhaps only when they have the same parent, I don't know.

                  S Offline
                  S Offline
                  StudentScripter
                  wrote on last edited by
                  #15

                  @JonB well i gess i screw the approach of trying to do this in the model and instead handle all the moving and dropping in my qtreeview subclass directly.
                  May @SGaist have a last word on if this is something that i definitely shouldn't do?

                  JonBJ 1 Reply Last reply
                  0
                  • S StudentScripter

                    @JonB well i gess i screw the approach of trying to do this in the model and instead handle all the moving and dropping in my qtreeview subclass directly.
                    May @SGaist have a last word on if this is something that i definitely shouldn't do?

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

                    @StudentScripter said in QTreeView how to support move action?:

                    @JonB well i gess i screw the approach of trying to do this in the model and instead handle all the moving and dropping in my qtreeview subclass directly.

                    I don't understand what you mean. Your code does stuff in ViewLayerStandartItemModel which is QStandardItemModel.

                    S 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @StudentScripter said in QTreeView how to support move action?:

                      @JonB well i gess i screw the approach of trying to do this in the model and instead handle all the moving and dropping in my qtreeview subclass directly.

                      I don't understand what you mean. Your code does stuff in ViewLayerStandartItemModel which is QStandardItemModel.

                      S Offline
                      S Offline
                      StudentScripter
                      wrote on last edited by StudentScripter
                      #17

                      @JonB Yes but i can't get it to work by handling the methodes in the model directly. Instead i may gonna do this by accesing the model trough my QTreeView Drag and Drop Events. This seems way easier to me.

                      
                      void ViewLayerList::dragMoveEvent(QDragMoveEvent *event)
                      {
                      
                       QTreeView::dragMoveEvent(event);
                      
                      QModelIndex belowIndex;
                      
                          // Überprüfen Sie die Position des Drop-Indikators
                          QAbstractItemView::DropIndicatorPosition position = dropIndicatorPosition();
                      
                          // Bestimmen Sie das Aussehen des Drop-Indikators basierend auf seiner Position
                          switch (position) {
                              case QAbstractItemView::AboveItem:
                              case QAbstractItemView::BelowItem:
                                  qDebug() << "Drop AboveItem or BelowItem";
                                  DropOnItem = false;
                      
                                  // Holen Sie sich den QModelIndex des Elements unterhalb der aktuellen Position
                                  belowIndex = indexAt(event->position().toPoint() + QPoint(0, 1));
                                  if (belowIndex.isValid()) {
                                      // Holen Sie sich die Zeile des Elements
                                      RowBelowDropPositon = belowIndex.row();
                                      qDebug() << "Row of item below: " << RowBelowDropPositon;
                                  }
                                  //AN AI HIER BEKOMME ICH IMMER EIN VERBOTEN SCHILD UND KANN ES NICHT DROPPEN
                                  event->acceptProposedAction();
                                  break;
                              case QAbstractItemView::OnItem:
                                  qDebug() << "Drop OnItem";
                                  DropOnItem = true;
                                  break;
                              case QAbstractItemView::OnViewport:
                                  qDebug() << "Drop OnViewport";
                                  
                                  break;
                          }
                      
                         
                         
                      }
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      void ViewLayerList::dropEvent(QDropEvent *event)
                      {
                      
                      if(DropOnItem == false){
                      
                      
                      }
                      
                      
                       
                      
                          QTreeView::dropEvent(event);
                      }
                      
                      
                      

                      But i don't know if it has many downsides compared to doing this in the model directly. Thats what my question was to @SGaist

                      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