I'm porting a Tkinter application to PyQt. This is my first time using PyQt so
I realize I may be doing this all wrong. My application includes a QTreeView
backed by my own model. The view provides the user a means to hierarchically
create, edit and organize large amounts of information. Ordering of the nodes
in the tree is important. Consequently I've implemented several ways for the
user to reorganize the tree including drag and drop reordering.
I've tried using QTreeView's built-in drag and drop. It works OK, but I really
need more than it can provide. The built-in drag and drop always drops content
<i>before</i> the entry under the mouse cursor. However, I want to be able to
drop content <i>before</i>, <i>after</i> or <i>as a child of</i> the entry
under the mouse cursor. The location (before, after or as a child of) is
determined by the location of the drag cursor's hot spot relative to the
rectangle over which it is currently hovering. E.g. if the hot spot is
hovering over the <i>top half</i> of an entry, the drop would occur
<i>before</i> that entry, while if it's in the <i>bottom half</i> the drop
would occur <i>after</i> the entry. However, if it's in the <i>bottom half</I>
<B>and</b> more than 20 pixels to the right of the left edge of the entry, it
will be dropped as a child. To provide feedback to the user as to where the
drop will occur I wish to change the mouse cursor as the drag operation is
taking place.
To implement all of this I've subclassed QTreeView and overridden
mousePressEvent(), mouseMoveEvent(), dragMoveEvent(), dragEnterEvent(),
dragLeaveEvent() and dropEvent() (as per the drag and drop documentation in
TrollTech's Qt distribution). In my constructor I have the following code:
self.insertBefore_cursor =
RES.getDragCursor('OutlineView','DnD_insertBeforeCursor')
self.insertAfter_cursor =
RES.getDragCursor('OutlineView','DnD_insertAfterCursor')
self.insertChild_cursor =
RES.getDragCursor('OutlineView','DnD_insertChildCursor')
RES is a subclass object of python's SafeConfigParser which reads ini files.
My getDragCursor() reads in the following lines
[OutlineView]
DnD_insertBeforeCursor = resources/cursors/arrow_insertBefore.png:14:12
DnD_insertAfterCursor = resources/cursors/arrow_insertAfter.png:14:12
DnD_insertChildCursor = resources/cursors/arrow_insertChild.png:22:12
getDragCursor() returns a tuple of two: a QPixmap and a QPoint (the hot spot).
Next my dragMoveEvent()
def dragMoveEvent( self, event ):
referenceIndex,relation = self._dnd_insertionPos( event )
if relation == 'before':
pixmap, hotspot = self.insertBefore_cursor
elif relation == 'after':
pixmap, hotspot = self.insertAfter_cursor
elif relation == 'child':
pixmap, hotspot = self.insertChild_cursor
else:
raise Exception()
self.drag.setDragCursor( pixmap, QtCore.Qt.CopyAction +
QtCore.Qt.MoveAction )
self.drag.setHotSpot( hotspot )
_dnd_insertionPos() calls event.pos(), does a bit of math and returns a tuple
consisting of the referenceIndex (a QModelIndex for the item over which the
mouse cursur is hovering) and a relation string ('before', 'after' or 'child').
I use this second value to select a cursor.
When I run my software and attempt a drag, all I see is the built-in drag
cursor. My own cursors are never displayed. However, if I put a break point
after the setDragCursor(), my cursor DOES get displayed. This leads me to
suspect that I may need to make some sort of call after setDropCursor() to give
the event loop or drawing routines some processor time.
Thanks for the help.
Sorry about all the text here. I wanted to be sure to provide enough info to
allow a diagnosis. Also, sorry that I haven't provided any runnable code to
get a clearer indication of the problem. There's quite a bit of code and I
wasn't able to trim it down to a decent sized-example. My complete project is
up in googlecode in a project called MindTree if more context is needed to help
diagnose this (or if you're just curious).
_______________________________________________
PyQt mailing list [email protected]
http://www.riverbankcomputing.com/mailman/listinfo/pyqt