树状视图中自定义数据的哑剧类型

时间:2019-05-01 08:49:33

标签: qt qt5

树形视图中的项目包含一个类容器的实例。 我想在视图中实现拖放功能。

根据QT教程中要复制的数据,我需要指定mime类型,然后编写Mimedata和dropMimeData函数。

QT示例正在处理一个简单的字符串,因此我完全不知道如何在自定义对象的情况下实现这些功能。

1)在我的情况下,哑剧类型应该是什么?

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 个答案:

答案 0 :(得分:1)

您可以添加自定义的mime类型,以指定要拖放的容器的类型。有关详情,请参见此post

  

由源构造的QDrag对象包含它用来表示数据的MIME类型列表(从最合适的到最不合适的顺序),放置目标使用其中之一来访问数据。

首先,尝试找到兼容的标准mime类型。这些是IANA分配的最常见的一个。

如果您要查找的列表不在列表中,则可以标记自定义的列表,然后将数据序列化为QByteArray以共享。

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

现在,在您的自定义小部件中,不要忘了接受这种mime类型的删除:

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

您可以在此project中找到完整的示例。