Тип MIME для пользовательских данных в виде дерева - PullRequest
0 голосов
/ 01 мая 2019

Элементы в древовидном представлении содержат экземпляр контейнера класса. Я хочу реализовать функцию перетаскивания в представлении.

В соответствии с руководством по QT для копируемых данных мне нужно указать тип mime, а затем написать функции Mimedata и dropMimeData.

Пример QT имеет дело с простой строкой, поэтому я совершенно не понимаю, как реализовать эти функции в случае пользовательских объектов.

1) Каким должен быть тип mime в моем случае?

2) Как реализовать текущую функцию mimedata для данных объекта-контейнера?

3) Как реализовать текущую функцию dropmimedata для данных объекта-контейнера?

 /////////////////////////////////////////
 class Container
   {
   private:
    std::string stdstrContainerName;
    std::string stdstrPluginType;
    int iSegments;
    float fRadius;

   public:
     Container();
     Container(std::string , std::string ,  int , float);
     Container(const  Container& obj);  
    ~Container();
    std::string GetName();
    std::string GetType();
    void SetName(std::string stdstrName);
   };
  Q_DECLARE_METATYPE( Container )

  ////////////////////////////////////////////////////////////
  QMimeData *DragDropListModel::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();
            // I have a GetContainer function which returns the Container 
            //object and i can use the GetContainer instead of data function.
            stream << text;
        }
     }

     mimeData->setData("application/vnd.text.list", encodedData);
     return mimeData;
   }
   //////////////////////////////////////////////////////////////////
    bool DragDropListModel::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);
      beginRow++;
      }

   return true;
}

Заголовочный файл для TreeItem.

class TreeItem
{
 public:
   explicit TreeItem( const Container &data , TreeItem *parent = 0 );
 ~TreeItem();
 TreeItem *parent();
 void appendChild(TreeItem *child);

 TreeItem *child(int iNumber);
 int childCount() const;
 int childNumber() const;
 Container data() const;
 bool setData(const Container &data , QVariant value);
 void setContainer(const Container &data);
 bool insertChildren(int position, int count );
 bool removeChildren( int position  , int count );

 private:
    QList<TreeItem*> childItems;
    Container itemData;
    TreeItem* parentItem;
}

1 Ответ

1 голос
/ 01 мая 2019

Вы можете добавить свои собственные типы пантомимы, чтобы указать тип контейнера, который вы хотите перетащить. См. сообщение для деталей.

Объект QDrag, созданный источником, содержит список типов MIME, которые он использует для представления данных (упорядоченные от наиболее подходящих к наименее подходящим), и цель удаления использует один из них для доступа к данным.

Прежде всего, попробуйте найти совместимый стандартный тип пантомимы. Это наиболее распространенные из них, назначенные IANA .

Если того, кого вы ищете, нет в списке, вы можете пометить свой собственный и сериализовать свои данные в QByteArray, чтобы поделиться им.

QByteArray output;
// do whatever
mimeData->setData("my-awesome-mime-type", output);

Теперь, в вашем пользовательском виджете, не забудьте принять капли этого типа пантомимы:

void Window::dragEnterEvent(QDragEnterEvent *event)  {
    if (event->mimeData()->hasFormat("my-awesome-mime-type"))
        event->acceptProposedAction();
}

Вы можете найти полный пример в этом проекте .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...