Usare il drag and drop in Qt

Usare il drag and drop in Qt

Debbo dire che Qt mi sorprende sempre di più nella facilità di molte cose.

Certo, è sempre C++, e molto cose non sono subito intuitive; ma altre sono molto facili!

Oggi vediamo come usare il drag and drop in una nostra finestra; il target è un oggetto QPlainTextEdit, ma vale anche per altri componenti di testo.

Quello che vogliamo ottenere è una lista di file, lista creata trascinandoli sulla QPlainTextEdit; i file accettati saranno solo JPEG, JPG e PNG.

Prima di tutto, nel nostro designer, impostiamo il readOnly e leviamo il flag ad acceptDrops.

Bene, fatto questo vediamo il codice:

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void dragEnterEvent(QDragEnterEvent *event);
    void dropEvent(QDropEvent *event);

private:
    Ui::MainWindow *ui;
    QVector<QString> list;
};

#endif // MAINWINDOW_H

Prima includiamo alcune librerie per attivare gli eventi di trascinamento e rilascio, e creiamo due funzioni apposite.

// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setAcceptDrops(true);
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasUrls())
    {
        event->acceptProposedAction();
    }
}

void MainWindow::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasUrls())
    {
        foreach (QUrl url, event->mimeData()->urls())
        {
            QFileInfo f(url.toLocalFile());
            if(f.fileName().endsWith(".jpeg") || f.fileName().endsWith(".jpg") || f.fileName().endsWith(".png"))
            {
                ui->txtList->appendPlainText(url.toLocalFile());
                list.append(f.filePath());
            }
        }
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

Nella funzione dragEnterEvent ci limitiamo a controllare che gli oggetti che abbiamo trascinato abbiano un url; che si traduce nel fatto che sia file.

Nel caso accettiamo l'evento.

Nella funzione dropEvent, invece, controlliamo l'estensione del file, e se fa parte di quelle accettate, aggiungiamo una riga alla QPlainTextEdit e poi aggiungiamo il file alla lista.

Fate qualche prova per verificarne il funzionamento!

Enjoy!