使用 QTreeWidget (Qt4) 和拖放混合父节点和子节点
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一个简单的解决方法是将一个小函数连接到信号
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)