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

发布于 2024-11-24 12:25:19 字数 1829 浏览 1 评论 0原文

我正在使用 QTreeWidget 来显示父节点的树及其离开 节点。每个父节点可以有不同的叶节点,但叶节点不应该有 孩子们。用户应该能够通过拖动叶子在父母之间移动叶子 到新的职位。为了避免叶子掉到其他叶子上,我有 仅在叶子上设置 ItemIsDragEnabled,同时启用 ItemIsDropEnabled 父节点。如果 QTreeWidget 设置为“SingleSelection”,则效果很好。 但是,如果 SelectionMode 设置为 ExtendedSelection,您可以 一起选择叶子节点和父节点并将它们放在叶子上: https://i.sstatic.net /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 一起使用我会 也很开心)

I am using a QTreeWidget to display a tree of parent nodes with their leave
nodes. Each parent can have various leaf nodes but leaf nodes should have no
childs. The user should be able to move leaves between parents by dragging them
to the new position. To avoid leaves from being dropped on other leaves, I have
only set ItemIsDragEnabled on leaves while having ItemIsDropEnabled on
parent nodes. This works fine if the QTreeWidget is set to "SingleSelection".
However, if the SelectionMode is set to ExtendedSelection you are able to
select a leave and a parent node together and drop them both on a leaf: https://i.sstatic.net/Kil3y.jpg (Screenshot)

Here is the sample code:

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);
}

I googled quite a lot but could not come up with a solution. How can I keep child and parent nodes on their respective levels while using ExtendedSelection?

Do I have to
subclass QTreeWidget and override insertRows()? Is there any way to intercept
drag'n'drop actions on QTreeWidget so I could check if the action is ok? (If
there is a way to get this to work with QStandardItemModel/QTreeView I would be
happy too)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

各自安好 2024-12-01 12:25:19

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

One easy workaround is to connect a little function to the signal itemSelectionChanged that removes all items from the selection that are not of the same type as the last selected item. Works just perfect for me (and for other programs like the Warcraft 3 trigger editor)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文