5

我对 QTreeWidget 进行了子类化,将其dragDropMode设置为InternalMove并使用自定义项目填充它,其中一些可以拖动,其他接受 drop。用户可以按预期在树周围移动项目。但是我需要被通知项目顺序的变化并做出适当的反应。不幸的是,没有与我可以连接到的树内项目的移动相关的信号。

我尝试获取 QTreeWidget 的底层model()的句柄,然后连接到它的rowsMo​​ved信号,但它似乎没有在内部移动期间发出。

我重新实现了 QTreeWidget 的dropEvent(),但无法确定那里的目标行索引。

显然,内部移动根本不会调用dropMimeData()事件。

我可以尝试任何其他方法吗?谢谢。

4

3 回答 3

6

在 reimplementeddropEvent()中,您应该能够找到目标行索引和项目:

void
subclass::dropEvent(QDropEvent* event)
{
  QModelIndex index = indexAt(event->pos());
  if (!index.isValid()) {  // just in case
    event->setDropAction(Qt::IgnoreAction);
    return;
  }
  QTreeWidgetItem* destination_item = itemFromIndex(index);
  ....
}
于 2013-07-17T21:09:02.283 回答
3

OP 实际上询问如何获得有关内部 move的通知,即如何在没有子类 QTreeWidget 的情况下做到这一点(至少这是我使用internal move的方式,因为它是内置功能)。我刚刚找到了一种方法:连接到 QTreeWidget 模型的rowsInserted()信号!

connect(treeWidget->model(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(rowsInserted(const QModelIndex &, int, int)));
于 2014-05-10T13:18:31.770 回答
1

顺便说一句,我想出了另一种方法来找出哪个元素准确地移动到了哪里,它避开了整个dropIndicatorPosition()和相关的itemAbove()、itemBelow()混乱,或者在不同的项目之间移动时至少可以帮助补充它父母:

void MyTreeWidget::dropEvent(QDropEvent *event)
{
    // get the list of the items that are about to be dragged
    QList<QTreeWidgetItem*> dragItems = selectedItems();

    // find out their row numbers before the drag
    QList<int> fromRows;
    QTreeWidgetItem *item;
    foreach(item, dragItems) fromRows.append(indexFromItem(item).row());

    // the default implementation takes care of the actual move inside the tree
    QTreeWidget::dropEvent(event);

    // query the indices of the dragged items again
    QList<int> toRows;
    foreach(item, dragItems) toRows.append(indexFromItem(item).row());

    // notify subscribers in some useful way
    emit itemsMoved(fromRows, toRows);
}
于 2013-07-17T23:20:25.847 回答