SlideShare a Scribd company logo
Ch9.Drag and Drop
        Browny
      23, May, 2011
Outline


• Enabling Drag and Drop
• Supporting Custom Drag Types
• Clipboard Handling
Drag file onto Window (1/4)
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();

protected:
    void dragEnterEvent(QDragEnterEvent *event);
    void dropEvent(QDropEvent *event);

private:
    bool readFile(const QString &fileName);
    QTextEdit *textEdit;
};
Drag file onto Window (2/4)
       MainWindow::MainWindow()
       {
           textEdit = new QTextEdit;
           setCentralWidget(textEdit);

           textEdit->setAcceptDrops(false);
           setAcceptDrops(true);

           setWindowTitle(tr("Text Editor"));
       }


QTextEdit
setAcceptDrops(false)
                setAcceptDrops(true)
                      MainWindow
Drag file onto Window (3/4)
 void MainWindow::dragEnterEvent(QDragEnterEvent *event)
 {
     if (event->mimeData()->hasFormat("text/plain"))
         event->acceptProposedAction();
 }


Standard MIME types are defined by the Internet Assigned
Numbers Authority (IANA). They consist of a type and a subtype
separated by a slash.

The official list of MIME types is available at http://www.iana.org/
assignments/media-types/
Drag file onto Window (4/4)

void MainWindow::dropEvent(QDropEvent *event)
{
    QList<QUrl> urls = event->mimeData()->urls();
    if (urls.isEmpty())
        return;

    QString fileName = urls.first().toLocalFile();
    if (fileName.isEmpty())
        return;

    if (readFile(fileName))
        setWindowTitle(tr("%1 - %2").arg(fileName)
                                    .arg(tr("Drag File")));
}
Initiate a Drag and Accept a Drop
               (1/4)

• Create a QListWidget subclass that
  supports drag and drop
Initiate a Drag and Accept a Drop
               (2/4)
   class ProjectListWidget : public QListWidget
   {
       Q_OBJECT

   public:
       ProjectListWidget(QWidget *parent = 0);

   protected:
       void mousePressEvent(QMouseEvent *event);
       void mouseMoveEvent(QMouseEvent *event);
       void dragEnterEvent(QDragEnterEvent *event);
       void dragMoveEvent(QDragMoveEvent *event);
       void dropEvent(QDropEvent *event);

   private:
       void performDrag();                        QWidget
                                       5
        QPoint startPos;
   };
Initiate a Drag and Accept a Drop
               (3/4)
ProjectListWidget::ProjectListWidget(QWidget *parent)
    : QListWidget(parent)
{
    setAcceptDrops(true);
}

void ProjectListWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
        startPos = event->pos();
    QListWidget::mousePressEvent(event);
}

void ProjectListWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        int distance = (event->pos() - startPos).manhattanLength();
        if (distance >= QApplication::startDragDistance())
            performDrag();
    }
    QListWidget::mouseMoveEvent(event);
}
Initiate a Drag and Accept a Drop
                   (4/4)
void ProjectListWidget::performDrag()
{
    QListWidgetItem *item = currentItem();
    if (item) {
        QMimeData *mimeData = new QMimeData;
        mimeData->setText(item->text());

         QDrag *drag = new QDrag(this);
         drag->setMimeData(mimeData);                QDrag
         drag->setPixmap(QPixmap(":/images/person.png"));
         if (drag->exec(Qt::MoveAction) == Qt::MoveAction)
             delete item;
     }                       QDrag::exec()
}
void ProjectListWidget::dragEnterEvent(QDragEnterEvent *event)
{
                                          ProjectListWidget
    ProjectListWidget *source =
            qobject_cast<ProjectListWidget *>(event->source());
    if (source && source != this) {
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
}

void ProjectListWidget::dropEvent(QDropEvent *event)
{
    ProjectListWidget *source =
            qobject_cast<ProjectListWidget *>(event->source());
    if (source && source != this) {
        addItem(event->mimeData()->text());
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
}
Drag custom data (1/2)
1. Provide arbitrary data as a QByteArray using
   QMimeData::setData() and extract it later
   using QMimeData::data()
2. Subclass QMimeData and re-implement
   formats() and retrieveData() to handle our
   custom data types
3. For drag and drop operations within a
   single application, we can subclass
   QMimeData and store the data using any
   data structure we want
Drag custom data (2/2)

• Drawbacks of Method 1
 ‣ Need	
  to	
  convert	
  our	
  data	
  structure	
  to	
  a	
  
      QByteArray	
  even	
  if	
  the	
  drag	
  is	
  not	
  ul1mately	
  
      accepted
 ‣ Providing	
  several	
  MIME	
  types	
  to	
  interact	
  nicely	
  
      with	
  a	
  wide	
  range	
  of	
  applica=ons,	
  we	
  need	
  to	
  
      store	
  the	
  data	
  several	
  1mes
 ‣ If	
  the	
  data	
  is	
  large,	
  this	
  can	
  slow	
  down	
  the	
  
      applica1on	
  needlessly
Add drag and drop capabilities to a
          QTableWidget (1/3)

   • Method 1
void MyTableWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        int distance = (event->pos() - startPos).manhattanLength();
        if (distance >= QApplication::startDragDistance())
            performDrag();
    }
    QTableWidget::mouseMoveEvent(event);
}
Add drag and drop capabilities to a
              QTableWidget (2/3)
void MyTableWidget::performDrag()
{
    QString plainText = selectionAsPlainText();   Chap4 (p.87)
    if (plainText.isEmpty())
        return;

    QMimeData *mimeData = new QMimeData;
    mimeData->setText(plainText);
    mimeData->setHtml(toHtml(plainText));
    mimeData->setData("text/csv", toCsv(plainText).toUtf8());

    QDrag *drag = new QDrag(this);
    drag->setMimeData(mimeData);
    if (drag->exec(Qt::CopyAction | Qt::MoveAction) == Qt::MoveAction)
        deleteSelection();
}
Add drag and drop capabilities to a
          QTableWidget (3/3)
void MyTableWidget::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat("text/csv")) {
        QByteArray csvData = event->mimeData()->data("text/csv");
        QString csvText = QString::fromUtf8(csvData);
        ...
        event->acceptProposedAction();
    } else if (event->mimeData()->hasFormat("text/plain")) {
        QString plainText = event->mimeData()->text();
        ...
        event->acceptProposedAction();
    }
}
           QTableWidget         Html       OK
Subclass QMimeData (1/3)
class TableMimeData : public QMimeData
{
    Q_OBJECT

public:
    TableMimeData(const QTableWidget *tableWidget,
                  const QTableWidgetSelectionRange &range);

     const QTableWidget *tableWidget() const { return myTableWidget; }
     QTableWidgetSelectionRange range() const { return myRange; }
     QStringList formats() const;

protected:
    QVariant retrieveData(const QString &format,
                          QVariant::Type preferredType) const;

private:
    static QString toHtml(const QString &plainText);
    static QString toCsv(const QString &plainText);

     QString text(int row, int column) const;
     QString rangeAsPlainText() const;

     const QTableWidget *myTableWidget;                          ,
     QTableWidgetSelectionRange myRange;
     QStringList myFormats;                 QTableWidget                 ,
};
Subclass QMimeData (2/3)
TableMimeData::TableMimeData(const QTableWidget *tableWidget,
                             const QTableWidgetSelectionRange &range) {
    myTableWidget = tableWidget;
    myRange = range;
    myFormats << "text/csv" << "text/html" << "text/plain";
}

QStringList TableMimeData::formats() const {
    return myFormats;
}

QVariant TableMimeData::retrieveData(const QString &format,
                                      QVariant::Type preferredType) const {
    if (format == "text/plain")
         return rangeAsPlainText();
    else if (format == "text/csv")
         return toCsv(rangeAsPlainText());
    else if (format == "text/html") {
         return toHtml(rangeAsPlainText());
    else
         return QMimeData::retrieveData(format, preferredType);
}
Subclass QMimeData (3/3)
void MyTableWidget::dropEvent(QDropEvent *event)
{
    const TableMimeData *tableData =
            qobject_cast<const TableMimeData *>(event->mimeData());

    if (tableData) {
        const QTableWidget *otherTable = tableData->tableWidget();
        QTableWidgetSelectionRange otherRange = tableData->range();
        ...
        event->acceptProposedAction();
    } else if (event->mimeData()->hasFormat("text/csv")) {
        QByteArray csvData = event->mimeData()->data("text/csv");
        QString csvText = QString::fromUtf8(csvData);
        ...

                                           we can directly access the table
    }
    QTableWidget::mouseMoveEvent(event);   data instead of going through
                                           QMimeData's API
}
Clipboard Handling

• Access clipboard: QApplication::clipboard()
• Built-in functionality might not be sufficient
   (not just text or an image)
  ‣ Subclass	
  QMimeData	
  and	
  re-­‐implement	
  a	
  few	
  virtual	
  
       func=ons	
  
  ‣ Reuse	
  the	
  QMimeData	
  subclass	
  and	
  put	
  it	
  on	
  the	
  
       clipboard	
  using	
  the	
  setMimeData()	
  func=on.	
  To	
  retrieve	
  
       the	
  data,	
  we	
  can	
  call	
  mimeData()	
  on	
  the	
  clipboard

• Clipboard's contents change
  ‣ QClipboard::dataChanged()	
  signal
Thank you :)

More Related Content

What's hot (19)

PPTX
Angular2 rxjs
Christoffer Noring
 
PDF
The Ring programming language version 1.10 book - Part 106 of 212
Mahmoud Samir Fayed
 
PDF
Sustaining Test-Driven Development
AgileOnTheBeach
 
PDF
The Ring programming language version 1.5.3 book - Part 8 of 184
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.5 book - Part 12 of 31
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.5.4 book - Part 8 of 185
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.5.1 book - Part 7 of 180
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.5.1 book - Part 12 of 180
Mahmoud Samir Fayed
 
PPTX
Rxjs ppt
Christoffer Noring
 
PDF
Rxjs vienna
Christoffer Noring
 
PDF
AJUG April 2011 Cascading example
Christopher Curtin
 
PDF
Vaadin 7 Today and Tomorrow
Joonas Lehtinen
 
PDF
The Ring programming language version 1.7 book - Part 101 of 196
Mahmoud Samir Fayed
 
PPTX
KDD 2016 Streaming Analytics Tutorial
Neera Agarwal
 
PPTX
OpenMAMA Under the Hood
OpenMAMA
 
PDF
Vaadin today and tomorrow
Joonas Lehtinen
 
PDF
The Ring programming language version 1.9 book - Part 74 of 210
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.8 book - Part 71 of 202
Mahmoud Samir Fayed
 
DOC
Qtp+real time+test+script
Ramu Palanki
 
Angular2 rxjs
Christoffer Noring
 
The Ring programming language version 1.10 book - Part 106 of 212
Mahmoud Samir Fayed
 
Sustaining Test-Driven Development
AgileOnTheBeach
 
The Ring programming language version 1.5.3 book - Part 8 of 184
Mahmoud Samir Fayed
 
The Ring programming language version 1.5 book - Part 12 of 31
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.4 book - Part 8 of 185
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 7 of 180
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 12 of 180
Mahmoud Samir Fayed
 
Rxjs vienna
Christoffer Noring
 
AJUG April 2011 Cascading example
Christopher Curtin
 
Vaadin 7 Today and Tomorrow
Joonas Lehtinen
 
The Ring programming language version 1.7 book - Part 101 of 196
Mahmoud Samir Fayed
 
KDD 2016 Streaming Analytics Tutorial
Neera Agarwal
 
OpenMAMA Under the Hood
OpenMAMA
 
Vaadin today and tomorrow
Joonas Lehtinen
 
The Ring programming language version 1.9 book - Part 74 of 210
Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 71 of 202
Mahmoud Samir Fayed
 
Qtp+real time+test+script
Ramu Palanki
 

Similar to [C++ gui programming with qt4] chap9 (7)

PDF
The Ring programming language version 1.9 book - Part 103 of 210
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.9 book - Part 96 of 210
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.7 book - Part 105 of 196
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.4.1 book - Part 28 of 31
Mahmoud Samir Fayed
 
ODP
Dn d clipboard
pinnamur
 
ODP
Dn d clipboard
pinnamur
 
ODP
Dn d clipboard
pinnamur
 
The Ring programming language version 1.9 book - Part 103 of 210
Mahmoud Samir Fayed
 
The Ring programming language version 1.9 book - Part 96 of 210
Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 105 of 196
Mahmoud Samir Fayed
 
The Ring programming language version 1.4.1 book - Part 28 of 31
Mahmoud Samir Fayed
 
Dn d clipboard
pinnamur
 
Dn d clipboard
pinnamur
 
Dn d clipboard
pinnamur
 
Ad

More from Shih-Hsiang Lin (13)

PDF
Introduction to Apache Ant
Shih-Hsiang Lin
 
PDF
Introduction to GNU Make Programming Language
Shih-Hsiang Lin
 
KEY
Ch6 file, saving states, and preferences
Shih-Hsiang Lin
 
PDF
Ch5 intent broadcast receivers adapters and internet
Shih-Hsiang Lin
 
PDF
Ch4 creating user interfaces
Shih-Hsiang Lin
 
PDF
Ch3 creating application and activities
Shih-Hsiang Lin
 
PDF
[C++ GUI Programming with Qt4] chap7
Shih-Hsiang Lin
 
PPTX
[C++ GUI Programming with Qt4] chap4
Shih-Hsiang Lin
 
PPTX
Function pointer
Shih-Hsiang Lin
 
PPT
Introduction to homography
Shih-Hsiang Lin
 
PPTX
Git basic
Shih-Hsiang Lin
 
PPTX
Project Hosting by Google
Shih-Hsiang Lin
 
PDF
An Introduction to Hidden Markov Model
Shih-Hsiang Lin
 
Introduction to Apache Ant
Shih-Hsiang Lin
 
Introduction to GNU Make Programming Language
Shih-Hsiang Lin
 
Ch6 file, saving states, and preferences
Shih-Hsiang Lin
 
Ch5 intent broadcast receivers adapters and internet
Shih-Hsiang Lin
 
Ch4 creating user interfaces
Shih-Hsiang Lin
 
Ch3 creating application and activities
Shih-Hsiang Lin
 
[C++ GUI Programming with Qt4] chap7
Shih-Hsiang Lin
 
[C++ GUI Programming with Qt4] chap4
Shih-Hsiang Lin
 
Function pointer
Shih-Hsiang Lin
 
Introduction to homography
Shih-Hsiang Lin
 
Git basic
Shih-Hsiang Lin
 
Project Hosting by Google
Shih-Hsiang Lin
 
An Introduction to Hidden Markov Model
Shih-Hsiang Lin
 
Ad

Recently uploaded (20)

PDF
epi editorial commitee meeting presentation
MIPLM
 
PPTX
TRANSLATIONAL AND ROTATIONAL MOTION.pptx
KIPAIZAGABAWA1
 
PPTX
How to Create Odoo JS Dialog_Popup in Odoo 18
Celine George
 
PPTX
Post Dated Cheque(PDC) Management in Odoo 18
Celine George
 
PPTX
DAY 1_QUARTER1 ENGLISH 5 WEEK- PRESENTATION.pptx
BanyMacalintal
 
PPTX
DIGITAL CITIZENSHIP TOPIC TLE 8 MATATAG CURRICULUM
ROBERTAUGUSTINEFRANC
 
PPTX
CATEGORIES OF NURSING PERSONNEL: HOSPITAL & COLLEGE
PRADEEP ABOTHU
 
PPTX
EDUCATIONAL MEDIA/ TEACHING AUDIO VISUAL AIDS
Sonali Gupta
 
PPTX
Cultivation practice of Litchi in Nepal.pptx
UmeshTimilsina1
 
PDF
Exploring the Different Types of Experimental Research
Thelma Villaflores
 
PPTX
How to Send Email From Odoo 18 Website - Odoo Slides
Celine George
 
PDF
Governor Josh Stein letter to NC delegation of U.S. House
Mebane Rash
 
PPTX
Difference between write and update in odoo 18
Celine George
 
PPTX
care of patient with elimination needs.pptx
Rekhanjali Gupta
 
PPTX
Introduction to Biochemistry & Cellular Foundations.pptx
marvinnbustamante1
 
PDF
Stokey: A Jewish Village by Rachel Kolsky
History of Stoke Newington
 
PDF
Council of Chalcedon Re-Examined
Smiling Lungs
 
PPTX
Universal immunization Programme (UIP).pptx
Vishal Chanalia
 
PPTX
HUMAN RESOURCE MANAGEMENT: RECRUITMENT, SELECTION, PLACEMENT, DEPLOYMENT, TRA...
PRADEEP ABOTHU
 
PDF
Aprendendo Arquitetura Framework Salesforce - Dia 03
Mauricio Alexandre Silva
 
epi editorial commitee meeting presentation
MIPLM
 
TRANSLATIONAL AND ROTATIONAL MOTION.pptx
KIPAIZAGABAWA1
 
How to Create Odoo JS Dialog_Popup in Odoo 18
Celine George
 
Post Dated Cheque(PDC) Management in Odoo 18
Celine George
 
DAY 1_QUARTER1 ENGLISH 5 WEEK- PRESENTATION.pptx
BanyMacalintal
 
DIGITAL CITIZENSHIP TOPIC TLE 8 MATATAG CURRICULUM
ROBERTAUGUSTINEFRANC
 
CATEGORIES OF NURSING PERSONNEL: HOSPITAL & COLLEGE
PRADEEP ABOTHU
 
EDUCATIONAL MEDIA/ TEACHING AUDIO VISUAL AIDS
Sonali Gupta
 
Cultivation practice of Litchi in Nepal.pptx
UmeshTimilsina1
 
Exploring the Different Types of Experimental Research
Thelma Villaflores
 
How to Send Email From Odoo 18 Website - Odoo Slides
Celine George
 
Governor Josh Stein letter to NC delegation of U.S. House
Mebane Rash
 
Difference between write and update in odoo 18
Celine George
 
care of patient with elimination needs.pptx
Rekhanjali Gupta
 
Introduction to Biochemistry & Cellular Foundations.pptx
marvinnbustamante1
 
Stokey: A Jewish Village by Rachel Kolsky
History of Stoke Newington
 
Council of Chalcedon Re-Examined
Smiling Lungs
 
Universal immunization Programme (UIP).pptx
Vishal Chanalia
 
HUMAN RESOURCE MANAGEMENT: RECRUITMENT, SELECTION, PLACEMENT, DEPLOYMENT, TRA...
PRADEEP ABOTHU
 
Aprendendo Arquitetura Framework Salesforce - Dia 03
Mauricio Alexandre Silva
 

[C++ gui programming with qt4] chap9

  • 1. Ch9.Drag and Drop Browny 23, May, 2011
  • 2. Outline • Enabling Drag and Drop • Supporting Custom Drag Types • Clipboard Handling
  • 3. Drag file onto Window (1/4) class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); protected: void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); private: bool readFile(const QString &fileName); QTextEdit *textEdit; };
  • 4. Drag file onto Window (2/4) MainWindow::MainWindow() { textEdit = new QTextEdit; setCentralWidget(textEdit); textEdit->setAcceptDrops(false); setAcceptDrops(true); setWindowTitle(tr("Text Editor")); } QTextEdit setAcceptDrops(false) setAcceptDrops(true) MainWindow
  • 5. Drag file onto Window (3/4) void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("text/plain")) event->acceptProposedAction(); } Standard MIME types are defined by the Internet Assigned Numbers Authority (IANA). They consist of a type and a subtype separated by a slash. The official list of MIME types is available at http://www.iana.org/ assignments/media-types/
  • 6. Drag file onto Window (4/4) void MainWindow::dropEvent(QDropEvent *event) { QList<QUrl> urls = event->mimeData()->urls(); if (urls.isEmpty()) return; QString fileName = urls.first().toLocalFile(); if (fileName.isEmpty()) return; if (readFile(fileName)) setWindowTitle(tr("%1 - %2").arg(fileName) .arg(tr("Drag File"))); }
  • 7. Initiate a Drag and Accept a Drop (1/4) • Create a QListWidget subclass that supports drag and drop
  • 8. Initiate a Drag and Accept a Drop (2/4) class ProjectListWidget : public QListWidget { Q_OBJECT public: ProjectListWidget(QWidget *parent = 0); protected: void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); void dropEvent(QDropEvent *event); private: void performDrag(); QWidget 5 QPoint startPos; };
  • 9. Initiate a Drag and Accept a Drop (3/4) ProjectListWidget::ProjectListWidget(QWidget *parent) : QListWidget(parent) { setAcceptDrops(true); } void ProjectListWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) startPos = event->pos(); QListWidget::mousePressEvent(event); } void ProjectListWidget::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { int distance = (event->pos() - startPos).manhattanLength(); if (distance >= QApplication::startDragDistance()) performDrag(); } QListWidget::mouseMoveEvent(event); }
  • 10. Initiate a Drag and Accept a Drop (4/4) void ProjectListWidget::performDrag() { QListWidgetItem *item = currentItem(); if (item) { QMimeData *mimeData = new QMimeData; mimeData->setText(item->text()); QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); QDrag drag->setPixmap(QPixmap(":/images/person.png")); if (drag->exec(Qt::MoveAction) == Qt::MoveAction) delete item; } QDrag::exec() }
  • 11. void ProjectListWidget::dragEnterEvent(QDragEnterEvent *event) { ProjectListWidget ProjectListWidget *source = qobject_cast<ProjectListWidget *>(event->source()); if (source && source != this) { event->setDropAction(Qt::MoveAction); event->accept(); } } void ProjectListWidget::dropEvent(QDropEvent *event) { ProjectListWidget *source = qobject_cast<ProjectListWidget *>(event->source()); if (source && source != this) { addItem(event->mimeData()->text()); event->setDropAction(Qt::MoveAction); event->accept(); } }
  • 12. Drag custom data (1/2) 1. Provide arbitrary data as a QByteArray using QMimeData::setData() and extract it later using QMimeData::data() 2. Subclass QMimeData and re-implement formats() and retrieveData() to handle our custom data types 3. For drag and drop operations within a single application, we can subclass QMimeData and store the data using any data structure we want
  • 13. Drag custom data (2/2) • Drawbacks of Method 1 ‣ Need  to  convert  our  data  structure  to  a   QByteArray  even  if  the  drag  is  not  ul1mately   accepted ‣ Providing  several  MIME  types  to  interact  nicely   with  a  wide  range  of  applica=ons,  we  need  to   store  the  data  several  1mes ‣ If  the  data  is  large,  this  can  slow  down  the   applica1on  needlessly
  • 14. Add drag and drop capabilities to a QTableWidget (1/3) • Method 1 void MyTableWidget::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { int distance = (event->pos() - startPos).manhattanLength(); if (distance >= QApplication::startDragDistance()) performDrag(); } QTableWidget::mouseMoveEvent(event); }
  • 15. Add drag and drop capabilities to a QTableWidget (2/3) void MyTableWidget::performDrag() { QString plainText = selectionAsPlainText(); Chap4 (p.87) if (plainText.isEmpty()) return; QMimeData *mimeData = new QMimeData; mimeData->setText(plainText); mimeData->setHtml(toHtml(plainText)); mimeData->setData("text/csv", toCsv(plainText).toUtf8()); QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); if (drag->exec(Qt::CopyAction | Qt::MoveAction) == Qt::MoveAction) deleteSelection(); }
  • 16. Add drag and drop capabilities to a QTableWidget (3/3) void MyTableWidget::dropEvent(QDropEvent *event) { if (event->mimeData()->hasFormat("text/csv")) { QByteArray csvData = event->mimeData()->data("text/csv"); QString csvText = QString::fromUtf8(csvData); ... event->acceptProposedAction(); } else if (event->mimeData()->hasFormat("text/plain")) { QString plainText = event->mimeData()->text(); ... event->acceptProposedAction(); } } QTableWidget Html OK
  • 17. Subclass QMimeData (1/3) class TableMimeData : public QMimeData { Q_OBJECT public: TableMimeData(const QTableWidget *tableWidget, const QTableWidgetSelectionRange &range); const QTableWidget *tableWidget() const { return myTableWidget; } QTableWidgetSelectionRange range() const { return myRange; } QStringList formats() const; protected: QVariant retrieveData(const QString &format, QVariant::Type preferredType) const; private: static QString toHtml(const QString &plainText); static QString toCsv(const QString &plainText); QString text(int row, int column) const; QString rangeAsPlainText() const; const QTableWidget *myTableWidget; , QTableWidgetSelectionRange myRange; QStringList myFormats; QTableWidget , };
  • 18. Subclass QMimeData (2/3) TableMimeData::TableMimeData(const QTableWidget *tableWidget, const QTableWidgetSelectionRange &range) { myTableWidget = tableWidget; myRange = range; myFormats << "text/csv" << "text/html" << "text/plain"; } QStringList TableMimeData::formats() const { return myFormats; } QVariant TableMimeData::retrieveData(const QString &format, QVariant::Type preferredType) const { if (format == "text/plain") return rangeAsPlainText(); else if (format == "text/csv") return toCsv(rangeAsPlainText()); else if (format == "text/html") { return toHtml(rangeAsPlainText()); else return QMimeData::retrieveData(format, preferredType); }
  • 19. Subclass QMimeData (3/3) void MyTableWidget::dropEvent(QDropEvent *event) { const TableMimeData *tableData = qobject_cast<const TableMimeData *>(event->mimeData()); if (tableData) { const QTableWidget *otherTable = tableData->tableWidget(); QTableWidgetSelectionRange otherRange = tableData->range(); ... event->acceptProposedAction(); } else if (event->mimeData()->hasFormat("text/csv")) { QByteArray csvData = event->mimeData()->data("text/csv"); QString csvText = QString::fromUtf8(csvData); ... we can directly access the table } QTableWidget::mouseMoveEvent(event); data instead of going through QMimeData's API }
  • 20. Clipboard Handling • Access clipboard: QApplication::clipboard() • Built-in functionality might not be sufficient (not just text or an image) ‣ Subclass  QMimeData  and  re-­‐implement  a  few  virtual   func=ons   ‣ Reuse  the  QMimeData  subclass  and  put  it  on  the   clipboard  using  the  setMimeData()  func=on.  To  retrieve   the  data,  we  can  call  mimeData()  on  the  clipboard • Clipboard's contents change ‣ QClipboard::dataChanged()  signal