You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在QGraphicsScene的dropEvent中获取拖拽的QTreeWidgetItem数据

解决QTreeWidget拖拽条目到QGraphicsScene无法获取条目信息的问题

你遇到的问题是因为Qt模型视图框架的拖拽逻辑,QTreeWidget默认不会将条目文本写入MIME的text字段,而是将选中条目的所有角色数据序列化后存储在application/x-qabstractitemmodeldatalist格式的二进制数据中,所以直接读取text()和objectName()都会返回空值,以下是两种可行解决方案:


方法1:直接解析Qt默认MIME数据

不需要修改现有QTreeWidget的代码,直接在dropEvent中解析二进制数据即可,适合仅需要读取条目内置角色(如显示文本、图标等)的场景:

void Scene::dropEvent(QGraphicsSceneDragDropEvent* event) {
  if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist")) {
    QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
    QDataStream stream(&itemData, QIODevice::ReadOnly);

    int row, col;
    QMap<int, QVariant> roleDataMap;
    // 循环读取所有被拖拽的条目数据
    while (!stream.atEnd()) {
      stream >> row >> col >> roleDataMap;
      // 示例:取第一列的显示文本,需要其他列调整col值即可
      if (col == 0) {
        QString itemText = roleDataMap[Qt::DisplayRole].toString();
        // 此处拿到文本后即可创建对应的矩形对象
        qDebug() << "拖拽条目文本:" << itemText;
      }
    }
  }
  event->acceptProposedAction();
}

如果需要读取条目存储的自定义数据,只需把Qt::DisplayRole替换为你自定义的Qt::UserRole枚举值即可。


方法2:自定义拖拽MIME数据(更灵活)

如果需要传递更复杂的自定义信息,推荐重写QTreeWidget的startDrag方法,自行构造MIME数据,后续读取逻辑更简单:

  1. 子类化QTreeWidget,重写startDrag虚函数:
// MyTreeWidget.h 声明
class MyTreeWidget : public QTreeWidget {
  Q_OBJECT
protected:
  void startDrag(Qt::DropActions supportedActions) override;
};

// MyTreeWidget.cpp 实现
void MyTreeWidget::startDrag(Qt::DropActions supportedActions) {
  QList<QTreeWidgetItem*> selected = selectedItems();
  if (selected.isEmpty()) return;

  QMimeData* mime = new QMimeData();
  // 直接存入你需要的条目信息
  mime->setText(selected.first()->text(0));
  // 如需传递自定义数据可以用自定义MIME格式存储
  // mime->setData("application/x-my-custom-item", selected.first()->data(0, Qt::UserRole).toByteArray());

  QDrag* drag = new QDrag(this);
  drag->setMimeData(mime);
  drag->exec(supportedActions);
}
  1. 将原有代码中m_nodeList的实例类型从QTreeWidget替换为MyTreeWidget,初始化配置不需要修改,之后在dropEvent中直接读取即可:
void Scene::dropEvent(QGraphicsSceneDragDropEvent* event) {
  if (event->mimeData()->hasText()) {
    QString itemText = event->mimeData()->text();
    // 直接使用文本创建矩形对象即可
  }
  event->acceptProposedAction();
}

内容的提问来源于stack exchange,提问作者Jepessen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:36:10