[PyQt] Drag-and-drop editing in QListWidget or QListView
Nathan Weston
nathan at genarts.com
Wed Jun 22 18:27:36 BST 2011
On 6/7/2011 7:53 AM, Nathan Weston wrote:
>
>
> On 06/02/2011 07:42 PM, David Boddie wrote:
>> The draganddrop/puzzle example provided with PyQt uses a QListWidget to
>> display a collection of puzzle pieces that can be dropped inside or
>> outside
>> the list, though it's not exactly the most user friendly interface you
>> could imagine.
>>
>> The itemviews/puzzle example is more or less the same, but uses QListView
>> instead of QListWidget. It implements support for drag and drop in a
>> custom model, which is based on QAbstractListModel to make it as
>> simple as
>> possible. Strangely, the piece movement is quite a bit more intuitive
>> than
>> in the other example.
>>
>
> Thanks, that got me started in the right direction. It seems that I
> basically have to reimplement the InternalMove behavior myself -- it has
> some nice visual touches that aren't duplicated in the examples.
>
> This leaves me wondering, though -- if InternalMove doesn't give you any
> way to find out when things move, what's the point?
>
Update: after going around in circles with this for quite some time, I
came to the conclusion that I really want to stick with the default drag
and drop implementation using InternalMove. As soon as I override any
part of that, I have to reimplement a ton of stuff (the pixmap for the
QDrag(), the target indicators in the ListWidget, etc).
In case anyone is interested, this is the solution I came up with. It
overrides startDrag and dropEvent in QListWidget in order to get the
dragged item along with its old/new indices, but calls the superclass
methods to do all the actual work.
It seems a little hacked-up to me, but it works.
It might be slightly cleaner to decode the the mime data in dropEvent --
I think this can hypothetically be decoded back into a QListWidgetItem.
But I couldn't quite figure out how to do it.
class DragAndDropList(QListWidget):
itemMoved = pyqtSignal(int, int, QListWidgetItem) # Old index, new
index, item
def __init__(self, parent=None, **args):
super(DragAndDropList, self).__init__(parent, **args)
self.setAcceptDrops(True)
self.setDragEnabled(True)
self.setDragDropMode(QAbstractItemView.InternalMove)
self.drag_item = None
self.drag_row = None
def dropEvent(self, event):
super(DragAndDropList, self).dropEvent(event)
self.itemMoved.emit(self.drag_row, self.row(self.drag_item),
self.drag_item)
self.drag_item = None
def startDrag(self, supportedActions):
self.drag_item = self.currentItem()
self.drag_row = self.row(self.drag_item)
super(DragAndDropList, self).startDrag(supportedActions)
--
. . . . . . . . . . . . . . . . . . . . . . . . .
Nathan Weston nathan at genarts.com
GenArts, Inc. Tel: 617-492-2888
955 Mass. Ave Fax: 617-492-2852
Cambridge, MA 02139 USA www.genarts.com
More information about the PyQt
mailing list