Monday, January 27, 2014

Qt's Drag-and-Drop Architecture for Python and PyQt5
Pt. 2, The Drop Target

The Drop Target

A drop target in Qt is a widget (any QWidget derivative) in which:

  • The widget at some time sets self.setAcceptDrops(True)
  • The widget implements the dragEnterEvent() method
  • The widget implements the dropEvent() method

The widget may optionally implement the dragMoveEvent() and/or dragLeaveEvent() methods, but these are not usually required.

When a widget sets acceptDrops to True, it will be called at dragEnterEvent() when the mouse cursor of a user drag crosses into the widget's boundary rectangle. In this method your code inspects the purpose and content of the drag and decides if it's for you. The code can look at the modifier keys (is this an Alt/Option- or Control-drag?). It can look at the mouse buttons (left-button drag, or right-button?). It can interrogate the type and even the content of the data that would be dropped.

If dragEnterEvent() rejects the drag, nothing further happens—the mouse cursor might change to show that this drag is not allowed, or not. But no other drag-related event methods will be delivered to this widget for this drag.

If the dragEnterEvent() code indicates that the drag is acceptable, more things will happen. The cursor will move across your widget's surface, and your dragMoveEvent(), if implemented, will be called repeatedly as it does so. The cursor may wander out of your widget without dropping; if so, your dragLeaveEvent() will be called, if implemented.

Or, the user may release the mouse button over your widget. Then your dropEvent() is called. At this point you can still reject the drag; otherwise your code is supposed to take the data out of the drag and do something with it.

If this sounds complex, it is. Fortunately many Qt widgets handle drops automatically. For example, QListView and QTableView handle dragging and dropping, and it's a blessing that they do.

In the next post we'll review the design of a drag source widget.

No comments: