Dropping
In both Qt 3 and Qt 4, it is possible to prepare a custom widget to accept dropped data by enabling the acceptDrops property of a widget, usually in the widget's constructor. As a result, the widget will receive drag enter events that can be handled by its dragEnterEvent() function. As in Qt 3, custom widgets in Qt 4 handle these events by determining whether the data supplied by the drag and drop operation can be dropped onto the widget. Since the classes used to encapsulate MIME data are different in Qt 3 and Qt 4, the exact implementations differ.
In Qt 3, the drag enter event is handled by checking whether each of the standard QDragObject subclasses can decode the data supplied, and indicating success or failure of these checks via the event's accept() function, as shown in this simple example:
void MyQt3Widget::dragEnterEvent(QDragEnterEvent* event)
{
event->accept(
QTextDrag::canDecode(event) ||
QImageDrag::canDecode(event)
);
}
In Qt 4, you can examine the MIME type describing the data to determine whether the widget should accept the event or, for common data types, you can use convenience functions:
void MyWidget::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasText() || event->mimeData()->hasImage())
event->acceptProposedAction();
}
The widget has some control over the type of drag and drop operation to be performed. In the above code, the action proposed by the drag source is accepted, but this can be overridden if required.
In both Qt 3 and Qt 4, it is necessary to accept a given drag event in order to receive the corresponding drop event. A custom widget in Qt 3 that can accept dropped data in the form of text or images might provide an implementation of dropEvent() that looks like the following:
void MyQt3Widget::dropEvent(QDropEvent* event)
{
QImage image;
QString text;
if ( QImageDrag::decode(event, image) ) {
insertImageAt(image, event->pos());
} else if ( QTextDrag::decode(event, text) ) {
insertTextAt(text, event->pos());
}
}
In Qt 4, the event is handled in a similar way:
void MyWidget::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasText())
dataLabel->setText(event->mimeData()->text());
else if (event->mimeData()->hasImage()) {
QVariant imageData = event->mimeData()->imageData();
dataLabel->setPixmap(qvariant_cast<QPixmap>(imageData));
}
event->acceptProposedAction();
}
It is also possible to extract data stored for a particular MIME type if it was specified by the drag source.
MIME Types and Data
In Qt 3, data to be transferred in drag and drop operations is encapsulated in instances of QDragObject and its subclasses, representing specific data formats related to common MIME type and subtypes.
In Qt 4, only the QMimeData class is used to represent data, providing a container for data stored in multiple formats, each associated with a relevant MIME type. Since arbitrary MIME types can be specified, there is no need for an extensive class hierarchy to represent different kinds of information. Additionally, QMimeData it provides some convenience functions to allow the most common data formats to be stored and retrieved with less effort than for arbitrary MIME types.
[Previous: Porting to Qt 4 - Virtual Functions]
[Contents]
[Next: Porting UI Files to Qt 4]