QTreeWidget通过拖动重新排序子项

Posted

技术标签:

【中文标题】QTreeWidget通过拖动重新排序子项【英文标题】:QTreeWidget reordering child items by dragging 【发布时间】:2014-02-12 13:41:11 【问题描述】:

我有一个 QTreeWidget,它只显示一个根节点和一层子节点。 我需要允许重新排序子节点。 他们绝不能被重新抚养。

这就是我在 QTreeWidget 中启用项目拖动的方式:

ui->levelElements->setSelectionMode(QAbstractItemView::SingleSelection);
ui->levelElements->setDragEnabled(true);
ui->levelElements->viewport()->setAcceptDrops(true);
ui->levelElements->setDropIndicatorShown(true);
ui->levelElements->setDragDropMode(QAbstractItemView::InternalMove);

根项是这样插入的:

pItem = new QTreeWidgetItem(ui->levelElements);
pItem->setText(0, node.firstChild().nodeValue());
pItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled);

当我在视图中插入一个孩子时,它是这样声明的:

pItem = new QTreeWidgetItem();
pItem->setText(0, strFileName);
pItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
pTreeRoot->addChild(pItem);

此时,我可以拖动一个子项并将其“重新插入”到子项列表中。我也可以将它移到根级别 - 这是我不想要的。

我使用的是 QT Creator v3,所以 QTreeWidget 在我的 UI 定义文件中。

我错过了什么吗?

【问题讨论】:

也许这会有所帮助:qtcentre.org/threads/… 【参考方案1】:

例如你可以重写:virtual void dropEvent(QDropEvent * event)

#include <QApplication>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QDropEvent>

class TreeView: public QTreeWidget

public:
  TreeView()
  
    resize(200, 300);

    setSelectionMode(QAbstractItemView::SingleSelection);
    setDragEnabled(true);
    viewport()->setAcceptDrops(true);
    setDropIndicatorShown(true);
    setDragDropMode(QAbstractItemView::InternalMove);

    QTreeWidgetItem* parentItem = new QTreeWidgetItem(this);
    parentItem->setText(0, "Test");
    parentItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled);

    for(int i = 0; i < 10; ++i)
    
      QTreeWidgetItem* pItem = new QTreeWidgetItem(parentItem);
      pItem->setText(0, QString("Number %1").arg(i) );
      pItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
      pItem->addChild(pItem);
    
  

private:
  virtual void  dropEvent(QDropEvent * event)
  
    QModelIndex droppedIndex = indexAt( event->pos() );

    if( !droppedIndex.isValid() )
      return;

    QTreeWidget::dropEvent(event);
  
;

int main(int argc, char *argv[])

    QApplication a(argc, argv);

    TreeView widget;
    widget.show();

    return a.exec();

【讨论】:

感谢您提供的信息。但是,我不知道如何从设计器文件中更改由 UI 初始化的类(记住我使用的是 Qt Creator)。有没有办法解决这个问题? 您可以在 Qt Creator 中将标准 QTreeWidget 升级为 TreeView(youtube.com/watch?v=Yt-YCxgEnyw) 存在更丑陋的解决方案(解决方法继承):为您的 QTreeView 对象安装EventFilter 并捕获 QDropEvent。

以上是关于QTreeWidget通过拖动重新排序子项的主要内容,如果未能解决你的问题,请参考以下文章

PyQt4 中的多列(可能使用 QTreeWidget)

QTreeWidget childAt(int x, int y) 返回 NULL

通过拖动重新排序ListView的元素[重复]

如何将 QTreeWidget 的子项设置为在单击其父项时自动选择并突出显示

在PyQt5中的QTreeWidget和QListWidget之间拖动项目?

在 PyQt QTreeWidget 中移动节点位置