【问题标题】:How can copy with drag and drop from one list but use move for internal drag and drop如何从一个列表中拖放复制但使用移动进行内部拖放
【发布时间】:2017-03-04 03:50:06
【问题描述】:

我需要能够将项目从一个 listWidget 复制到另一个。这很容易做到,但我似乎无法找到一种方法来根据被拖动的项目是否起源于它被拖放到的列表来区分拖放操作,而不必用我的几乎所有拖放功能覆盖自己的。当我将一个项目从一个列表拖到另一个列表时,我想复制它,但是当我在同一个列表中拖动项目时,我想移动它。

我一直在研究设置mimetypes,但是我必须编写自己的mouseMoveEvent 来判断拖动项目的来源,但到目前为止,尝试这样做会破坏一切。在不覆盖 mouseMoveEvent 的情况下是否无法为项目设置 mime 类型?

由于我拖动的项目是自定义的,因此当它被移动或复制到第二个列表时,我必须编写自己的定义来重建它。使用默认的拖动功能,这一切都适用于内部移动。但是到目前为止,我还没有弄清楚如何在拖动是内部移动时使用默认的拖放功能,然后在拖放来自不同列表时切换到我的自定义功能来复制项目。

import sys
from PyQt4 import QtGui , QtCore


def main():

    app = QtGui.QApplication(sys.argv)

    w = QtGui.QWidget()
    w.resize(250, 150)
    w.move(300, 300)
    w.setWindowTitle('Simple')
    layout=QtGui.QHBoxLayout(w)
    dragList=DragDropListWidget()
    layout.addWidget(dragList)
    dragList.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
    dragList.name='dragList'
    dragList.populate(['one','two','three'])
    dragList2=DragDropListWidget()
    dragList2.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
    dragList2.name='dragList'


    layout.addWidget(dragList2)
    w.show()

    sys.exit(app.exec_())

class scriptsWidget(QtGui.QWidget):


    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self)

        self.name=''

        self.widget_QHBoxLayout = QtGui.QHBoxLayout(self)
        self.widget_QHBoxLayout.setSpacing(0)
        self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0)

        self.name_QLabel = QtGui.QLabel(self)
        self.widget_QHBoxLayout.addWidget(self.name_QLabel)

        self.user_QLabel = QtGui.QLabel(self)
        self.widget_QHBoxLayout.addWidget(self.user_QLabel)

        self.widget_QHBoxLayout.setSpacing(0)
        self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0)



    def setName(self,name):
        self.name_QLabel.setText(name)
        self.name=name

    def setUser(self,user):
        self.user_QLabel.setText(user)

class customQListWidgetItem(QtGui.QListWidgetItem):


    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self)
        self.name=''

    def setName(self,name):
        self.name=name   




class DragDropListWidget(QtGui.QListWidget):
    _drag_info = []
    def __init__(self, parent = None):

        super(DragDropListWidget, self).__init__(parent)


        self.name=''


    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()

        else:
            super(DragDropListWidget, self).dragMoveEvent(event)


    def dropEvent(self, event):
        if event.mimeData().hasText():
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            self.emit(QtCore.SIGNAL("dropped"), links)

        else:
            event.setDropAction(QtCore.Qt.CopyAction)
            items = []
            for index in xrange(self.count()):
                items.append(self.item(index))

            super(DragDropListWidget, self).dropEvent(event)

            for index in xrange(self.count()):
                if self.item(index) not in items:
                    self.populateDrop(self.item(index), index, [self.item(index).data(QtCore.Qt.UserRole).toPyObject()])

    def populateDrop(self,item,row,items=[]):
        for i in items:
            widget = scriptsWidget()
            widget.setName(i)
            widget.setUser('x')
            self.takeItem(row)
            item = customQListWidgetItem()
            item.setName(i)
            item.setWhatsThis(i)
            data = (i)
            item.setData(QtCore.Qt.UserRole, data)
            self.insertItem (row, item)
            self.setItemWidget(item,widget)



    def populate(self,items=[]):
        self.clear()
        for i in items:
            print(i)
            widget = scriptsWidget()
            widget.setName(i)
            widget.setUser('x')
            item = customQListWidgetItem()
            item.setName(i)
            data = (i)
            item.setData(QtCore.Qt.UserRole, data)
            self.addItem(item)
            self.setItemWidget(item,widget)



if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python drag-and-drop pyqt qlistwidget qlistwidgetitem


    【解决方案1】:

    这就是我想出的。单击该项目时,我正在设置一个类数据变量,以便在删除该项目时可以知道它的来源。我尝试在 DragDropListWidget 中使用类变量,但由于某种原因,它只会存储当前列表的本地名称.. 很奇怪。全局变量也可以使用,但不可取。

    import sys
    from PyQt4 import QtGui , QtCore
    
    def main():
    
        app = QtGui.QApplication(sys.argv)
    
        w = QtGui.QWidget()
        w.resize(250, 150)
        w.move(300, 300)
        w.setWindowTitle('Simple')
        layout=QtGui.QHBoxLayout(w)
        dragList=DragDropListWidget()
        layout.addWidget(dragList)
        d=data()
        dragList.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
        dragList.name='dragList'
        dragList.populate(['one','two','three'])
        dragList.data=d
        dragList2=DragDropListWidget()
        dragList2.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
        dragList2.name='dragList2'
        dragList2.external='dragList2'
        dragList2.data=d
    
    
        layout.addWidget(dragList2)
        w.show()
    
        sys.exit(app.exec_())
    
    class data(object):
        def __init__(self, parent=None):
            self.origin='new'
    
    
    
    
    class scriptsWidget(QtGui.QWidget):
    
    
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self)
    
            self.name=''
    
            self.widget_QHBoxLayout = QtGui.QHBoxLayout(self)
            self.widget_QHBoxLayout.setSpacing(0)
            self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0)
    
            self.name_QLabel = QtGui.QLabel(self)
            self.widget_QHBoxLayout.addWidget(self.name_QLabel)
    
            self.user_QLabel = QtGui.QLabel(self)
            self.widget_QHBoxLayout.addWidget(self.user_QLabel)
    
            self.widget_QHBoxLayout.setSpacing(0)
            self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0)
    
    
    
        def setName(self,name):
            self.name_QLabel.setText(name)
            self.name=name
    
        def setUser(self,user):
            self.user_QLabel.setText(user)
    
    class customQListWidgetItem(QtGui.QListWidgetItem):
    
    
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self)
            self.name=''
            self.list=''
    
        def setName(self,name):
            self.name=name   
    
    
    
    
    class DragDropListWidget(QtGui.QListWidget):
    
        def __init__(self, parent = None):
    
            super(DragDropListWidget, self).__init__(parent)
            self._dropping = False
            self.itemPressed.connect(self.clicked)
    
            self.data=''
    
            self.name=''
            self.external=''
            self.internal=False
    
        def clicked(self):
            global origin 
            self.data.origin=self.name
    
    
        def dragMoveEvent(self, event):
    
            if event.mimeData().hasUrls():
                event.setDropAction(QtCore.Qt.CopyAction)
                event.accept()
    
            else:
    
                super(DragDropListWidget, self).dragMoveEvent(event)
    
    
        def dropEvent(self, event):
    
            if event.mimeData().hasText():
                event.setDropAction(QtCore.Qt.CopyAction)
                event.accept()
                links = []
                for url in event.mimeData().urls():
                    links.append(str(url.toLocalFile()))
                self.emit(QtCore.SIGNAL("dropped"), links)
    
            else:
                if self.external is self.name and self.data.origin is not self.name:
                    print('external')
                    event.setDropAction(QtCore.Qt.CopyAction)
                    items = []
                    for index in xrange(self.count()):
                        items.append(self.item(index))
                    print items
    
                    super(DragDropListWidget, self).dropEvent(event)
    
                    for index in xrange(self.count()):
                        if self.item(index) not in items:
                            print(index)
                            self.populateDrop(self.item(index), index, [self.item(index).data(QtCore.Qt.UserRole).toPyObject()])
    
                else:
                    print('internal')
                    event.setDropAction(QtCore.Qt.MoveAction)
    
                    super(DragDropListWidget, self).dropEvent(event)
    
            self.data.origin = None       
    
        def populateDrop(self,item,row,items=[]):
            for i in items:
                widget = scriptsWidget()
                widget.setName(i)
                widget.setUser('x')
                self.takeItem(row)
                item = customQListWidgetItem()
                item.setName(i)
                item.setWhatsThis(i)
                item.list=self.name
                data = (i)
                item.setData(QtCore.Qt.UserRole, data)
                self.insertItem (row, item)
                self.setItemWidget(item,widget)
    
    
    
        def populate(self,items=[]):
            self.clear()
            for i in items:
                print(i)
                widget = scriptsWidget()
                widget.setName(i)
                widget.setUser('x')
    
                item = customQListWidgetItem()
                item.setName(i)
                item.list=self.name
                data = (i)
                item.setData(QtCore.Qt.UserRole, data)
                self.addItem(item)
                self.setItemWidget(item,widget)
    
    
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      【解决方案2】:

      辨别拖动是来自这个小部件还是来自不同的小部件是微不足道的——只需在任何拖放事件中使用事件源即可。例如:

      void MyWidget::dragMoveEvent(QDragMoveEvent *event) 
      {
          if (event->source() != this) {
              // the drag comes from another widget
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-16
        • 2013-11-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多