Initiating drags

Initiating drag operations is a bit more difficult, because you must determine when exactly a drag begins. Users expect that holding down the mouse-button on the object they want to drag and moving it should start dragging. However, everyone moves the mouse very slightly, even if just single-clicking on an object. Thus, we must determine how many pixels the mouse pointer should move (while the first mouse button is depressed) to enter a drag operation.

We cannot do this using QMultiLineEdit. A class like QIconView offers special support for starting drags by allowing you to re-implement the dragObject function:

class MyIconView(QIconView):

      def dragObject(self):
          return QTextDrag(self.currentItem().text(), self)
    

Once you have determined what should start a drag (and this can be anything, really), starting a drag operation is a simple matter of creating a new QDragObject. This could be, for instance, a QTextDrag or a QImageDrag. Take care that you keep a reference to the drag object—if you delete it, or allow it to go out of scope, it will disappear.

In the next example, simply moving a mouse will start a drag operation:

Example 23-2. Drag and drop

#!/usr/bin/env python

from sys import argv
from qt import *


class DropDemo(QListView):
    def __init__(self,parent=None,name=None):
        QListView.__init__(self,parent,name)
        self.setAcceptDrops(1)
        self.setGeometry(10,10,100,60)
        self.addColumn("Column 1")
        self.i = QListViewItem(self, "Hello")
        self.ii = QListViewItem(self, "Hello 2")
        r = self.itemRect(self.i)
        r = self.itemRect(self.ii)
        
    def dragEnterEvent(self, event):
        event.accept(QTextDrag.canDecode(event))
  
    def dropEvent(self, event):
        text = QString()
        pos = QPoint(event.pos().x(), event.pos().y() - self.header().height())
        item = self.itemAt(pos)
        text=QString()
 
    def mouseMoveEvent(self, event):
        self.startDrag()

    def startDrag(self):
        d = QTextDrag("blabla",self) # keep a reference to d
        d.dragCopy()
 
if __name__ == '__main__':
    a = QApplication(argv)
    w = DropDemo()
    w.setCaption("Drag and Drop Test")
    w.resize(120,80)
    a.setMainWidget(w)
    w.show()
    a.exec_loop()