|  | Home · Examples

# Drop Site Example

The example shows how to distinguish the various MIME formats available in a drag and drop operation.

The Drop Site example accepts drops from other applications, and displays the MIME formats provided by the drag object.

There are two classes, `DropArea` and `DropSiteWindow`, and a `main()` function in this example. A `DropArea` object is instantiated in `DropSiteWindow`; a `DropSiteWindow` object is then invoked in the `main()` function.

## DropArea Class Definition

The `DropArea` class is a subclass of QLabel with a public slot, `clear()`, and a `changed()` signal.

    class DropArea : public QLabel
    {
        Q_OBJECT

    public:
        DropArea(QWidget *parent = 0);

    public slots:
        void clear();

    signals:
        void changed(const QMimeData *mimeData = 0);

In addition, `DropArea` also contains a private instance of QLabel and reimplementations of four QWidget event handlers:

1. dragEnterEvent()
2. dragMoveEvent()
3. dragLeaveEvent()
4. dropEvent()

These event handlers are further explained in the implementation of the `DropArea` class.

    protected:
        void dragEnterEvent(QDragEnterEvent *event);
        void dragMoveEvent(QDragMoveEvent *event);
        void dragLeaveEvent(QDragLeaveEvent *event);
        void dropEvent(QDropEvent *event);

    private:
        QLabel *label;
    };

## DropArea Class Implementation

In the `DropArea` constructor, we set the minimum size to 200x200 pixels, the frame style to both QFrame::Sunken and QFrame::StyledPanel, and we align its contents to the center.
The following code example is written in c++.

    DropArea::DropArea(QWidget *parent)
        : QLabel(parent)
    {
        setMinimumSize(200, 200);
        setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
        setAlignment(Qt::AlignCenter);
        setAcceptDrops(true);
        setAutoFillBackground(true);
        clear();
    }

Also, we enable drop events in `DropArea` by setting the acceptDrops property to `true`. Then, we enable the autoFillBackground property and invoke the `clear()` function.

The dragEnterEvent() event handler is called when a drag is in progress and the mouse enters the `DropArea` object. For the `DropSite` example, when the mouse enters `DropArea`, we set its text to "<drop content>" and highlight its background.Error parsing snippet. Then, we invoke acceptProposedAction() on `event`, setting the drop action to the one proposed. Lastly, we emit the `changed()` signal, with the data that was dropped and its MIME type information as a parameter.

For dragMoveEvent(), we just accept the proposed QDragMoveEvent object, `event`, with acceptProposedAction().Error parsing snippet. The `DropArea` class's implementation of dropEvent() extracts the `event`'s mime data and displays it accordingly.Error parsing snippet. The `mimeData` object can contain one of the following objects: an image, HTML text, plain text, or a list of URLs.Error parsing snippet.

- If `mimeData` contains an image, we display it in `DropArea` with setPixmap().
- If `mimeData` contains HTML, we display it with setText() and set `DropArea`'s text format as Qt::RichText.
- If `mimeData` contains plain text, we display it with setText() and set `DropArea`'s text format as Qt::PlainText. In the event that `mimeData` contains URLs, we iterate through the list of URLs to display them on individual lines.
- If `mimeData` contains other types of objects, we set `DropArea`'s text, with setText() to "Cannot display data" to inform the user.

We then set `DropArea`'s backgroundRole to QPalette::Dark and we accept `event`'s proposed action.Error parsing snippet. The dragLeaveEvent() event handler is called when a drag is in progress and the mouse leaves the widget.Error parsing snippet. For `DropArea`'s implementation, we clear invoke `clear()` and then accept the proposed event.

The `clear()` function sets the text in `DropArea` to "<drop content>" and sets the backgroundRole to QPalette::Dark. Lastly, it emits the `changed()` signal.Error parsing snippet.

## DropSiteWindow Class Definition

The `DropSiteWindow` class contains a constructor and a public slot, `updateFormatsTable()`.

    class DropSiteWindow : public QWidget
    {
        Q_OBJECT

    public:
        DropSiteWindow();

    public slots:
        void updateFormatsTable(const QMimeData *mimeData);

    private:
        DropArea *dropArea;
        QLabel *abstractLabel;
        QTableWidget *formatsTable;

        QPushButton *clearButton;
        QPushButton *quitButton;
        QDialogButtonBox *buttonBox;
    };

The class also contains a private instance of `DropArea`, `dropArea`, QLabel, `abstractLabel`, QTableWidget, `formatsTable`, QDialogButtonBox, `buttonBox`, and two QPushButton objects, `clearButton` and `quitButton`.

## DropSiteWindow Class Implementation

In the constructor of `DropSiteWindow`, we instantiate `abstractLabel` and set its wordWrap property to `true`. We also call the adjustSize() function to adjust `abstractLabel`'s size according to its contents.
The following code example is written in c++.

    DropSiteWindow::DropSiteWindow()
    {
        abstractLabel = new QLabel(tr("This example accepts drags from other "
                                      "applications and displays the MIME types "
                                      "provided by the drag object."));
        abstractLabel->setWordWrap(true);
        abstractLabel->adjustSize();

Then we instantiate `dropArea` and connect its `changed()` signal to `DropSiteWindow`'s `updateFormatsTable()` slot.
The following code example is written in c++.

        dropArea = new DropArea;
        connect(dropArea, SIGNAL(changed(const QMimeData *)),
                this, SLOT(updateFormatsTable(const QMimeData *)));

We now set up the QTableWidget object, `formatsTable`. Its horizontal header is set using a QStringList object, `labels`. The number of columms are set to two and the table is not editable. Also, the `formatTable`'s horizontal header is formatted to ensure that its second column stretches to occupy additional space available.
The following code example is written in c++.

        QStringList labels;
        labels << tr("Format") << tr("Content");

        formatsTable = new QTableWidget;
        formatsTable->setColumnCount(2);
        formatsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
        formatsTable->setHorizontalHeaderLabels(labels);
        formatsTable->horizontalHeader()->setStretchLastSection(true);

Two QPushButton objects, `clearButton` and `quitButton`, are instantiated and added to `buttonBox` - a QDialogButtonBox object. We use QDialogButtonBox here to ensure that the push buttons are presented in a layout that conforms to the platform's style.
The following code example is written in c++.

        clearButton = new QPushButton(tr("Clear"));
        quitButton = new QPushButton(tr("Quit"));

        buttonBox = new QDialogButtonBox;
        buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole);
        buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);

        connect(quitButton, SIGNAL(pressed()), this, SLOT(close()));
        connect(clearButton, SIGNAL(pressed()), dropArea, SLOT(clear()));

The clicked() signals for `quitButton` and `clearButton` are connected to close() and `clear()`, respectively.

For the layout, we use a QVBoxLayout, `mainLayout`, to arrange our widgets vertically. We also set the window title to "Drop Site" and the minimum size to 350x500 pixels.
The following code example is written in c++.

        QVBoxLayout *mainLayout = new QVBoxLayout;
        mainLayout->addWidget(abstractLabel);
        mainLayout->addWidget(dropArea);
        mainLayout->addWidget(formatsTable);
        mainLayout->addWidget(buttonBox);
        setLayout(mainLayout);

        setWindowTitle(tr("Drop Site"));
        setMinimumSize(350, 500);
    }

We move on to the `updateFormatsTable()` function. This function updates the `formatsTable`, displaying the MIME formats of the object dropped onto the `DropArea` object. First, we set QTableWidget's rowCount property to 0. Then, we validate to ensure that the QMimeData object passed in is a valid object.Error parsing snippet. Once we are sure that `mimeData` is valid, we iterate through its supported formats using the foreach keyword. This keyword has the following format:

    foreach(variable, container)

In our example, `format` is the `variable` and the `container` is a QStringList, obtained from `mimeData->formats()`.

Note: The formats() function returns a QStringList object, containing all the formats supported by the `mimeData`.Error parsing snippet. Within each iteration, we create a QTableWidgetItem, `formatItem` and we set its flags to Qt::ItemIsEnabled, and its text alignment to Qt::AlignTop and Qt::AlignLeft.

A QString object, `text`, is customized to display data according to the contents of `format`. We invoke {QString}'s simplified() function on `text`, to obtain a string that has no additional space before, after or in between words.Error parsing snippet. If `format` contains a list of URLs, we iterate through them, using spaces to separate them. On the other hand, if `format` contains an image, we display the data by converting the text to hexadecimal.Error parsing snippet. Once `text` has been customized to contain the appropriate data, we insert both `format` and `text` into `formatsTable` with setItem(). Lastly, we invoke resizeColumnToContents() on `formatsTable`'s first column.

## The main() Function

Within the `main()` function, we instantiate `DropSiteWindow` and invoke its show() function.Error parsing snippet.