O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
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_OBJECTpublic:    MainWindow();protected:    void dra...
Drag file onto Window (2/4)       MainWindow::MainWindow()       {           textEdit = new QTextEdit;           setCentral...
Drag file onto Window (3/4) void MainWindow::dragEnterEvent(QDragEnterEvent *event) {     if (event->mimeData()->hasFormat(...
Drag file onto Window (4/4)void MainWindow::dropEvent(QDropEvent *event){    QList<QUrl> urls = event->mimeData()->urls(); ...
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   ...
Initiate a Drag and Accept a Drop               (3/4)ProjectListWidget::ProjectListWidget(QWidget *parent)    : QListWidge...
Initiate a Drag and Accept a Drop                   (4/4)void ProjectListWidget::performDrag(){    QListWidgetItem *item =...
void ProjectListWidget::dragEnterEvent(QDragEnterEvent *event){                                          ProjectListWidget...
Drag custom data (1/2)1. Provide arbitrary data as a QByteArray using   QMimeData::setData() and extract it later   using ...
Drag custom data (2/2)• Drawbacks of Method 1 ‣ Need	  to	  convert	  our	  data	  structure	  to	  a	        QByteArray	 ...
Add drag and drop capabilities to a          QTableWidget (1/3)   • Method 1void MyTableWidget::mouseMoveEvent(QMouseEvent...
Add drag and drop capabilities to a              QTableWidget (2/3)void MyTableWidget::performDrag(){    QString plainText...
Add drag and drop capabilities to a          QTableWidget (3/3)void MyTableWidget::dropEvent(QDropEvent *event){    if (ev...
Subclass QMimeData (1/3)class TableMimeData : public QMimeData{    Q_OBJECTpublic:    TableMimeData(const QTableWidget *ta...
Subclass QMimeData (2/3)TableMimeData::TableMimeData(const QTableWidget *tableWidget,                             const QT...
Subclass QMimeData (3/3)void MyTableWidget::dropEvent(QDropEvent *event){    const TableMimeData *tableData =            q...
Clipboard Handling• Access clipboard: QApplication::clipboard()• Built-in functionality might not be sufficient   (not just...
Thank you :)
Próximos SlideShares
Carregando em…5
×

[C++ gui programming with qt4] chap9

1.904 visualizações

Publicada em

  • Seja o primeiro a comentar

[C++ gui programming with qt4] chap9

  1. 1. Ch9.Drag and Drop Browny 23, May, 2011
  2. 2. Outline• Enabling Drag and Drop• Supporting Custom Drag Types• Clipboard Handling
  3. 3. Drag file onto Window (1/4)class MainWindow : public QMainWindow{ Q_OBJECTpublic: MainWindow();protected: void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event);private: bool readFile(const QString &fileName); QTextEdit *textEdit;};
  4. 4. Drag file onto Window (2/4) MainWindow::MainWindow() { textEdit = new QTextEdit; setCentralWidget(textEdit); textEdit->setAcceptDrops(false); setAcceptDrops(true); setWindowTitle(tr("Text Editor")); }QTextEditsetAcceptDrops(false) setAcceptDrops(true) MainWindow
  5. 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 AssignedNumbers Authority (IANA). They consist of a type and a subtypeseparated by a slash.The official list of MIME types is available at http://www.iana.org/assignments/media-types/
  6. 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. 7. Initiate a Drag and Accept a Drop (1/4)• Create a QListWidget subclass that supports drag and drop
  8. 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. 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. 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. 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. 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 types3. For drag and drop operations within a single application, we can subclass QMimeData and store the data using any data structure we want
  13. 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. 14. Add drag and drop capabilities to a QTableWidget (1/3) • Method 1void MyTableWidget::mouseMoveEvent(QMouseEvent *event){ if (event->buttons() & Qt::LeftButton) { int distance = (event->pos() - startPos).manhattanLength(); if (distance >= QApplication::startDragDistance()) performDrag(); } QTableWidget::mouseMoveEvent(event);}
  15. 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. 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. 17. Subclass QMimeData (1/3)class TableMimeData : public QMimeData{ Q_OBJECTpublic: 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. 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. 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 QMimeDatas API}
  20. 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• Clipboards contents change ‣ QClipboard::dataChanged()  signal
  21. 21. Thank you :)

×