Как перетащить из одного QListWidget в другой

В одном диалоговом окне находятся два QListWIdgets. Функциональность DragDrop была включена для обоих. Если я перетаскиваю файл на любой из двух ListWidges, программа распознает его и распечатывает список удаленных файлов. Но помимо перетаскивания файлов я хотел бы иметь возможность перетаскивать элементы виджета Список из одного в другой. Если я перетаскиваю ListItems, событие перетаскивания запускается. Но он не может распознать, какие предметы были сброшены на виджет. Пример кода приведен ниже. Цель состоит в том, чтобы перетащить элементы списка из одного ListWidget в другой.

import sys, os
from PyQt4 import QtCore, QtGui   
class ThumbListWidget(QtGui.QListWidget):
    def __init__(self, type, parent=None):
        super(ThumbListWidget, self).__init__(parent)
        self.setAcceptDrops(True)
        self.setIconSize(QtCore.QSize(124, 124))

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

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

    def dropEvent(self, event):
        if event.mimeData().hasUrls:
            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.ignore()


class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        super(QtGui.QMainWindow,self).__init__()
        self.listItems={}

        myQWidget = QtGui.QWidget()
        myBoxLayout = QtGui.QVBoxLayout()
        myQWidget.setLayout(myBoxLayout)
        self.setCentralWidget(myQWidget)

        self.listWidgetA = ThumbListWidget(self)
        for i in range(12): 
            QtGui.QListWidgetItem( 'Item '+str(i), self.listWidgetA )
        myBoxLayout.addWidget(self.listWidgetA)

        self.listWidgetB = ThumbListWidget(self)
        myBoxLayout.addWidget(self.listWidgetB)   

        self.listWidgetA.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
        self.listWidgetA.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.connect(self.listWidgetA, QtCore.SIGNAL("dropped"), self.items_dropped)
        self.listWidgetA.currentItemChanged.connect(self.item_clicked)

        self.listWidgetB.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
        self.listWidgetB.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.connect(self.listWidgetB, QtCore.SIGNAL("dropped"), self.items_dropped)
        self.listWidgetB.currentItemChanged.connect(self.item_clicked)

    def items_dropped(self, arg):
        print arg

    def item_clicked(self, arg):
        print arg

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())
РЕДАКТИРОВАТЬ № 2

Вот код, который делает все это. Но нет способа отследить, какой объект был сброшен. Методы dropOnA () и dropOnB () все еще не работают.

from PyQt4 import QtGui, QtCore
import sys, os


class MyClassItem(QtGui.QListWidgetItem):
    def __init__(self, parent=None):
        super(QtGui.QListWidgetItem, self).__init__(parent)       


class ThumbListWidget(QtGui.QListWidget):
    def __init__(self, type, parent=None):
        super(ThumbListWidget, self).__init__(parent)
        self.setIconSize(QtCore.QSize(124, 124))
        self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
        self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            super(ThumbListWidget, self).dragEnterEvent(event)

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

    def dropEvent(self, event):
        print 'dropEvent', event
        if event.mimeData().hasUrls():
            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.MoveAction)
            super(ThumbListWidget, self).dropEvent(event)


class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        super(QtGui.QMainWindow,self).__init__()
        self.listItems={}

        myQWidget = QtGui.QWidget()
        myBoxLayout = QtGui.QVBoxLayout()
        myQWidget.setLayout(myBoxLayout)
        self.setCentralWidget(myQWidget)

        self.listWidgetA = ThumbListWidget(self)
        self.listWidgetB = ThumbListWidget(self)

        for i in range(7):
            listItemAInstance=MyClassItem()
            listItemAInstance.setText('A'+'%04d'%i)
            listItemAInstance.setBackgroundColor(QtCore.Qt.darkGray)   
            if i%2: listItemAInstance.setBackgroundColor(QtCore.Qt.gray)
            self.listWidgetA.addItem(listItemAInstance) 

            listItemBInstance=MyClassItem()
            listItemBInstance.setText('B'+'%04d'%i)

            if i%2: listItemBInstance.setBackgroundColor(QtCore.Qt.lightGray)
            self.listWidgetB.addItem(listItemBInstance) 

        myBoxLayout.addWidget(self.listWidgetA)      

        myBoxLayout.addWidget(self.listWidgetB)   
        self.connect(self.listWidgetA, QtCore.SIGNAL("dropped"), self.droppedOnA)
        self.connect(self.listWidgetB, QtCore.SIGNAL("dropped"), self.droppedOnB)


    def droppedOnA(self, arg):
        print '\n\t droppedOnA', arg.text

    def droppedOnB(self, arg):
        print '\n\t droppedOnB', arg.text


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())
РЕДАКТИРОВАТЬ № 3

Вот еще одна попытка на этот раз с использованием MIME для передачи отброшенных объектов Item в ListWidget. К сожалению, cPickle отказывается принимать двоичные объекты, выбрасывающие

TypeError: тип sip.wrapper не может быть создан или переклассифицирован

Чтобы обойти это, я конвертирую каждое имя объекта в строку и использую его со словарем self.listItems = {} в качестве ключа для получения двоичных объектов списка. Который, кажется, работает хорошо. Но в конце, когда я почти все это сделал, ListWidget без видимых ошибок не добавляет элемент «Drop» к самому себе ... Это странно.

self.listWidgetB.addItem (droppedItemInstance)

.

from PyQt4 import QtGui, QtCore
import sys, os
import cPickle 

class MyClassItem(QtGui.QListWidgetItem):
    def __init__(self, parent=None):
        super(QtGui.QListWidgetItem, self).__init__(parent)       


class ThumbListWidget(QtGui.QListWidget):
    def __init__(self, type, parent=None):
        super(ThumbListWidget, self).__init__(parent)
        self.setIconSize(QtCore.QSize(124, 124))
        self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
        self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            super(ThumbListWidget, self).dragEnterEvent(event)

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

    def dropEvent(self, event):

        if event.mimeData().hasUrls():
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))

        else:
            event.setDropAction(QtCore.Qt.MoveAction)
            super(ThumbListWidget, self).dropEvent(event)


    def mimeTypes(self):
        return ['bstream', 'text/xml']

    def mimeData(self, droppedItems):
        mimedata = QtCore.QMimeData()

        droppedItemsAsStrings=[]
        for each in droppedItems:            
            droppedItemsAsStrings.append( str(each) )

        bstream = cPickle.dumps(droppedItemsAsStrings)
        mimedata.setData('bstream', bstream)        
        return mimedata


    def dropMimeData(self, action, mimedata, row):

        if action == QtCore.Qt.IgnoreAction: return True  

        dropped=cPickle.loads(str(mimedata.data('bstream')))

        self.emit(QtCore.SIGNAL("dropped"), dropped)  

        return True


class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        super(QtGui.QMainWindow,self).__init__()
        self.listItems={}

        myQWidget = QtGui.QWidget()
        myBoxLayout = QtGui.QVBoxLayout()
        myQWidget.setLayout(myBoxLayout)
        self.setCentralWidget(myQWidget)

        self.listWidgetA = ThumbListWidget(self)
        self.listWidgetB = ThumbListWidget(self)

        for i in range(7):
            listItemAInstance=MyClassItem()
            listItemAInstance.setText('A'+'%04d'%i)
            listItemAInstance.setBackgroundColor(QtCore.Qt.darkGray)   
            if i%2: listItemAInstance.setBackgroundColor(QtCore.Qt.gray)
            self.listWidgetA.addItem(listItemAInstance) 

            listItemBInstance=MyClassItem()
            listItemBInstance.setText('B'+'%04d'%i)

            if i%2: listItemBInstance.setBackgroundColor(QtCore.Qt.lightGray)
            self.listWidgetB.addItem(listItemBInstance) 

            self.listItems[str(listItemAInstance)]=listItemAInstance
            self.listItems[str(listItemBInstance)]=listItemBInstance

        myBoxLayout.addWidget(self.listWidgetA)      

        myBoxLayout.addWidget(self.listWidgetB)   
        self.connect(self.listWidgetA, QtCore.SIGNAL("dropped"), self.droppedOnA)
        self.connect(self.listWidgetB, QtCore.SIGNAL("dropped"), self.droppedOnB)


    def droppedOnA(self, droppedItemsAsStrings):
        print '\n\t droppedOnA()'
        for each in droppedItemsAsStrings:
            if each in self.listItems.keys():
                droppedItemInstance = self.listItems[each]
                print 'adding', droppedItemInstance.text()
                self.listWidgetA.addItem(droppedItemInstance) 


    def droppedOnB(self, droppedItemsAsStrings):
        print '\n\t droppedOnB()'
        for each in droppedItemsAsStrings:
            if each in self.listItems.keys():
                droppedItemInstance = self.listItems[each]
                self.listWidgetB.addItem(droppedItemInstance) 
                print 'adding', droppedItemInstance.text()


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())

Ответы на вопрос(3)

Ваш ответ на вопрос