<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.6001.18148" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>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.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>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.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>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:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>
self.insertBefore_cursor =
RES.getDragCursor('OutlineView','DnD_insertBeforeCursor')<BR>
self.insertAfter_cursor =
RES.getDragCursor('OutlineView','DnD_insertAfterCursor')<BR>
self.insertChild_cursor =
RES.getDragCursor('OutlineView','DnD_insertChildCursor')</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>RES is a subclass object of python's
SafeConfigParser which reads ini files. My getDragCursor() reads in the
following lines</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>[OutlineView]<BR>DnD_insertBeforeCursor =
resources/cursors/arrow_insertBefore.png:14:12<BR>DnD_insertAfterCursor
=
resources/cursors/arrow_insertAfter.png:14:12<BR>DnD_insertChildCursor
= resources/cursors/arrow_insertChild.png:22:12</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>getDragCursor() returns a tuple of
two: a QPixmap and a QPoint (the hot spot). Next my
dragMoveEvent()</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> def dragMoveEvent( self, event
):<BR> referenceIndex,relation =
self._dnd_insertionPos( event )</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> if relation ==
'before':<BR> pixmap, hotspot =
self.insertBefore_cursor<BR> elif relation ==
'after':<BR> pixmap, hotspot =
self.insertAfter_cursor<BR> elif relation ==
'child':<BR> pixmap, hotspot =
self.insertChild_cursor<BR>
else:<BR> raise
Exception()<BR> <BR>
self.drag.setDragCursor( pixmap, QtCore.Qt.CopyAction + QtCore.Qt.MoveAction
)<BR> self.drag.setHotSpot( hotspot )</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>_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.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>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.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Thanks for the help.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV><FONT face=Arial size=2>
<DIV><BR>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).</DIV>
<DIV></FONT> </DIV></BODY></HTML>