使用QTreeWidget(Qt4)和拖放的混合父节点和子节点

时间:2011-07-16 09:59:54

标签: qt drag-and-drop qtreewidget

我正在使用QTreeWidget显示父节点树的假 节点。每个父节点可以有各种叶节点,但叶节点应该没有 孩子的。用户应该能够通过拖动来移动父母之间的叶子 到新的位置。为了避免叶子落在其他叶子上,我有 仅在ItemIsDragEnabled开启时在树叶上设置ItemIsDropEnabled 父节点。如果QTreeWidget设置为“SingleSelection”,这可以正常工作。 但是,如果SelectionMode设置为ExtendedSelection,您就可以 选择一个leave和一个父节点,然后将它们放在一片叶子上:http://i.stack.imgur.com/Kil3y.jpg(截图)

以下是示例代码:

QTreeWidget *tree = this->ui->treeWidget;
QTreeWidgetItem *item;
QTreeWidgetItem *child;
tree->setSelectionMode(QAbstractItemView::ExtendedSelection);
tree->setDefaultDropAction(Qt::MoveAction);
tree->setDragEnabled(true);
tree->setAcceptDrops(true);
tree->setDropIndicatorShown(true);

// disable dropping of leaves as top level items
tree->invisibleRootItem()->setFlags( Qt::ItemIsSelectable |
                Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );

for (int i = 0; i < 2; i++) {
    // create top level item
    item = new QTreeWidgetItem();
    item->setText(0, "parent");
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
                  | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled );

    // add 3 child items
    for (int j = 0; j < 3; j++) {
        child = new QTreeWidgetItem();
        child->setText(0, "child");
        child->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
                      | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled );
        item->addChild(child);
    }

    // add item to tree
    tree->addTopLevelItem(item);
}

我搜索了很多,但无法提出解决方案。如何在使用ExtendedSelection时将子节点和父节点保持在各自的级别?

我必须这样做吗? 子类QTreeWidget并覆盖insertRows()?有没有办法拦截 在QTreeWidget上拖放操作,以便我可以检查操作是否正常? (如果 有一种方法可以使用QStandardItemModel / QTreeView来实现这一点 也快乐)

1 个答案:

答案 0 :(得分:0)

一个简单的解决方法是将一个小函数连接到信号itemSelectionChanged,该信号将从选择中删除与上一个选定项目类型不同的所有项目。适用于我(以及其他程序,如魔兽争霸3触发编辑器)