Создание подклассов QListWidgetItem вам не поможет, поскольку данные перетаскивания всегда сериализуются, что означает, что ни одна ссылка на экземпляр никогда не обменивается.
Если ваши данные сериализуемы (очевидно, строки, но обычно подходит любой тип QVariant, например, QColor или QPixmap), вы можете просто использовать QListWidgetItem.setData()
с пользовательской ролью, определяемой c для каждого поля данных, которое вы хотите сохранить, а затем используйте QListWidgetItem.data()
, чтобы вернуть эти данные.
В этом случае я создал пользовательскую функцию, но это, очевидно, не нужно, так как вы можете просто вручную установить данные для каждого элемента до или после его вставки, если у вас есть правильный индекс строки.
MySpecialRole = QtCore.Qt.UserRole + 1
class DragAndDropList(QtWidgets.QListWidget):
def addCustomItem(self, name, data):
item = QtWidgets.QListWidgetItem(name)
item.setData(MySpecialRole, data)
self.addItem(item)
def dropEvent(self, event):
super().dropEvent(event)
# let's see the data for each item, including our custom role
for row in range(self.count()):
item = self.item(row)
print('Data for item {}: {}'.format(
row + 1, item.data(MySpecialRole)))
class MyCentralWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(MyCentralWidget, self).__init__(parent)
self.h_layout = QtWidgets.QHBoxLayout(self)
self.setLayout(self.h_layout)
self.list_left = DragAndDropList()
self.list_left.setDragEnabled(True)
self.list_right = DragAndDropList()
self.list_right.setAcceptDrops(True)
self.h_layout.addWidget(self.list_left)
self.h_layout.addWidget(self.list_right)
self.list_left.addCustomItem('item (using addCustomItem)', 'some data')
self.list_left.addItem('item without custom data')
self.list_left.addItem('this item will have data')
self.list_left.item(2).setData(MySpecialRole, 'some custom data')
Обратите внимание, что следующая строка выдаст вам ошибку:
self.emit(QtCore.SIGNAL("dropped"), links)
Мало того, что виджет списка не имеет атрибута emit
(как у любого другого подкласса QObject), но и пользовательские сигналы должны быть объявлены в определении класса, а затем отправлены напрямую.
class DragAndDropList(QtWidgets.QListWidget):
dropped = QtCore.pyqtSignal(object)
def dropEvent(self, event):
# ...
self.dropped.emit(links)