加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – pyside qtreewidget限制拖放

发布时间:2020-12-16 21:43:24 所属栏目:Python 来源:网络整理
导读:我正在尝试向QTreeWidget拖放功能添加约束,以防止分支进入另一个根中的另一个分支. 这是一个让事情更清晰的例子: 我有4个物体.让我们称他们为苹果,香蕉,胡萝卜,榴莲. 树看起来像这样: isDelicious (Root)|-- BackgroundObjects (Branch) |-- Durian|-- For

我正在尝试向QTreeWidget拖放功能添加约束,以防止分支进入另一个根中的另一个分支.

这是一个让事情更清晰的例子:
我有4个物体.让我们称他们为苹果,香蕉,胡萝卜,榴莲.

树看起来像这样:

isDelicious (Root)
|-- BackgroundObjects (Branch)
   |-- Durian
|-- ForgroundObjects (Branch)
   |-- Apple
   |-- Banana
   |-- Carrot
isSmelly (Root)
|-- BackgroundObjects (Branch)
   |-- Apple
   |-- Carrot
|-- ForgroundObjects (Branch)
   |-- Banana
   |-- Durian

因此,允许将对象从BackgroundObjects拖放到ForgroundObjects,反之亦然,但是不允许将它们拖放到不同根目录上的分支上.

我已经尝试重新实现和子类化dragMoveEvent,dragEnterEvent和dropEvent,如果我在dragEnterEvent中对事件调用accept,它将调用dragMoveEvent(我期望).但是,只有当我退出QTreeWidget时才会调用dropEvent.

我想要做的是在移动之前检查所选对象的祖父母,以及建议的新祖父母以查看它们是否相同.如果是,那么接受此举.否则忽略此举.

我已经搜索过是否有任何答案,到目前为止我还没有看到任何我正在尝试做的事情.可能最接近的是来自Stack Overflow的这两个问题:
https://stackoverflow.com/questions/17134289/managing-drag-and-drop-within-qtreewidgets-in-pyside
qt: QTreeView – limit drag and drop to only happen within a particlar grandparent (ancestor)

最佳答案
Qt似乎没有让这种事情变得非常容易.

我能想到的最好的方法是在拖动输入和拖动移动事件期间暂时重置项目标志.下面的示例动态计算当前顶级项目以禁止拖放.但也可以通过使用setData()为每个项添加标识符来完成.

from PyQt4 import QtCore,QtGui

class TreeWidget(QtGui.QTreeWidget):
    def __init__(self,parent=None):
        QtGui.QTreeWidget.__init__(self,parent)
        self.setDragDropMode(self.InternalMove)
        self.setDragEnabled(True)
        self.setDropIndicatorShown(True)
        self._dragroot = self.itemRootIndex()

    def itemRootIndex(self,item=None):
        root = self.invisibleRootItem()
        while item is not None:
            item = item.parent()
            if item is not None:
                root = item
        return QtCore.QPersistentModelIndex(
            self.indexFromItem(root))

    def startDrag(self,actions):
        items = self.selectedItems()
        self._dragroot = self.itemRootIndex(items and items[0])
        QtGui.QTreeWidget.startDrag(self,actions)

    def dragEnterEvent(self,event):
        self._drag_event(event,True)

    def dragMoveEvent(self,False)

    def _drag_event(self,event,enter=True):
        items = []
        disable = False
        item = self.itemAt(event.pos())
        if item is not None:
            disable = self._dragroot != self.itemRootIndex(item)
            if not disable:
                rect = self.visualItemRect(item)
                if event.pos().x() < rect.x():
                    disable = True
        if disable:
            for item in item,item.parent():
                if item is not None:
                    flags = item.flags()
                    item.setFlags(flags & ~QtCore.Qt.ItemIsDropEnabled)
                    items.append((item,flags))
        if enter:
            QtGui.QTreeWidget.dragEnterEvent(self,event)
        else:
            QtGui.QTreeWidget.dragMoveEvent(self,event)
        for item,flags in items:
            item.setFlags(flags)

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.tree = TreeWidget(self)
        self.tree.header().hide()
        def add(root,*labels):
            item = QtGui.QTreeWidgetItem(self.tree,[root])
            item.setFlags(item.flags() &
                          ~(QtCore.Qt.ItemIsDragEnabled |
                            QtCore.Qt.ItemIsDropEnabled))
            for index,title in enumerate(
                ('BackgroundObjects','ForegroundObjects')):
                subitem = QtGui.QTreeWidgetItem(item,[title])
                subitem.setFlags(
                    subitem.flags() & ~QtCore.Qt.ItemIsDragEnabled)
                for text in labels[index].split():
                    child = QtGui.QTreeWidgetItem(subitem,[text])
                    child.setFlags(
                        child.flags() & ~QtCore.Qt.ItemIsDropEnabled)
        add('isDelicious','Durian','Apple Banana Carrot')
        add('isSmelly','Apple Carrot','Banana Durian')
        root = self.tree.invisibleRootItem()
        root.setFlags(root.flags() & ~QtCore.Qt.ItemIsDropEnabled)
        self.tree.expandAll()
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.tree)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500,300,300)
    window.show()
    sys.exit(app.exec_())

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读