Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Seminarium Informatyka Prowadzący dr Grzegorz Wójcik

Podobne prezentacje


Prezentacja na temat: "Seminarium Informatyka Prowadzący dr Grzegorz Wójcik"— Zapis prezentacji:

1 Seminarium 2008. Informatyka Prowadzący dr Grzegorz Wójcik
Rozdział 9. Drag and drop. Seminarium 2008. Informatyka Prowadzący dr Grzegorz Wójcik

2 Plan Omówienie działania drag & drop’u Implementacja drag & drop’u
„File reader” „Choose project” Drag & drop + niestandardowe obiekty Drag & drop + schowek

3 Zasada Drag & Dropu Przeciągnięcie obiektu i upuszczenie go na Widget, bądź jego komponenty. Źródło: Komponent tej samej aplikacji Zewnętrzna aplikacja

4 File reader Aplikacja umożliwia przeciągnięcie listy URI (czyli
najprościej mówiąc zaznaczonego pliku/ów) na QTextBox’a, co skutkuje wczytaniem pliku i odpowiednio ustawieniem tytułu Widgeta.

5 File reader Definicja głównego okna
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; };

6 File reader Konstruktor. Ustawienie TextBoxa w centrum.
Ustawienie (nie)akceptowanych akcji. MainWindow::MainWindow() { textEdit = new QTextEdit; setCentralWidget(textEdit); textEdit->setAcceptDrops(false); setAcceptDrops(true); setWindowTitle(tr("Text Editor")); }

7 File reader dragEnterEvent. Sprawdzenie formatu przeciąganego obiektu.
Pozwolenie na wykonanie akcji. void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("text/uri-list")) event->acceptProposedAction(); }

8 File reader dropEvent. void MainWindow::dropEvent(QDropEvent *event) {
QList<QUrl> urls = event->mimeData()->urls(); if (urls.isEmpty()) return; QString fileName = urls.first().toLocalFile(); if (fileName.isEmpty()) if (readFile(fileName)) setWindowTitle(tr("%1 - %2").arg(fileName) .arg(tr("Drag File"))); }

9 Choose project Aplikacja umożliwia przeciągnięcie pracowników, aby
pracowali przy odpowiednich projektach.

10 Choose project Definicja klasy
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 startDrag(); QPoint startPos; };

11 Choose project Konstruktor.
ProjectListWidget::ProjectListWidget(QWidget *parent) : QListWidget(parent) { setAcceptDrops(true); }

12 Choose project Akcja wciśnięcia przycisku myszy na widget’ie.
void ProjectListWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) startPos = event->pos(); QListWidget::mousePressEvent(event); }

13 Choose project Akcja przesuwania myszy po widget’ie.
void ProjectListWidget::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { int distance = (event->pos() - startPos).manhattanLength(); if (distance >= QApplication::startDragDistance()) startDrag(); } QListWidget::mouseMoveEvent(event);

14 Choose project Rozpoczęcie drag’a. void ProjectListWidget::startDrag()
{ QListWidgetItem *item = currentItem(); if (item) { QMimeData *mimeData = new QMimeData; mimeData->setText(item->text()); QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); drag->setPixmap(QPixmap(":/images/person.png")); if (drag->start(Qt::MoveAction) == Qt::MoveAction) delete item; }

15 Choose project Akcja rozpoczęcia drag’a na widget’ie.
void ProjectListWidget::dragEnterEvent(QDragEnterEvent *event) { ProjectListWidget *source = qobject_cast<ProjectListWidget *>(event->source()); if (source && source != this) { event->setDropAction(Qt::MoveAction); event->accept(); }

16 Choose project Akcja drag’a na widget’ie.
void ProjectListWidget::dragMoveEvent(QDragMoveEvent *event) { ProjectListWidget *source = qobject_cast<ProjectListWidget *>(event->source()); if (source && source != this) { event->setDropAction(Qt::MoveAction); event->accept(); }

17 Choose project Akcja drop’u na widget’ie.
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(); }

18 Drag & drop + niestandardowe obiekty
Dlaczego? QMimeData nie wystarcza Typowe dane Pliki Zwykły tekst Chcemy przeciągać niestandardowe dane

19 Drag & drop + niestandardowe obiekty
Jak to zrobić? Możemy kodować nasz dane np. do QByteArray, a następnie używać QMimeData::setData() i QMimeData::data() Możemy stworzyć podklase QMimeData i nadpisać formats() i retrieveData() W przypadku akcji w obrębie jednej aplikacji, możemy stworzyć podklase QMimeData i trzymać dane w jakiejkolwiek strukturze

20 QTableWidget Widget ma możliwość konwertowania przeciągania
danych. W przypadku przeciągania danych zaznaczanych na widget’ie konwertuje je i wyświetla w odpowiednim formacie.

21 QTableWidget – I wersja
void MyTableWidget::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { int distance = (event->pos() - startPos).manhattanLength(); if (distance >= QApplication::startDragDistance()) startDrag(); } QTableWidget::mouseMoveEvent(event);

22 QTableWidget – I wersja
void MyTableWidget::startDrag() { QString plainText = selectionAsPlainText(); //analogicznie jak w Rozdziale 4. copy() 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->start(Qt::CopyAction | Qt::MoveAction) == Qt::MoveAction) deleteSelection(); }

23 QTableWidget – I wersja
QString MyTableWidget::toCsv(const QString &plainText) { QString result = plainText; result.replace("\\", "\\\\"); result.replace("\"", "\\\""); result.replace("\t", "\", \""); result.replace("\n", "\"\n\""); result.prepend("\""); result.append("\""); return result; }

24 QTableWidget – I wersja
QString MyTableWidget::toHtml(const QString &plainText) { QString result = Qt::escape(plainText); result.replace("\t", "<td>"); result.replace("\n", "\n<tr><td>"); result.prepend("<table>\n<tr><td>"); result.append("\n</table>"); return result; }

25 QTableWidget – I wersja
Red Green Blue //plainText Cyan Yellow Magenta "Red", "Green", "Blue„ //CSV "Cyan", "Yellow", "Magenta" <table> //HTML (prawie jak :-) <tr><td>Red<td>Green<td>Blue <tr><td>Cyan<td>Yellow<td>Magenta </table>

26 QTableWidget – I wersja
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(); }

27 QTableWidget – I wersja
Akceptujemy tylko 2 formaty. HTML – możemy przeciągnąć poza QTableWidget, ale na QTableWidget już nie przyjmujemy.

28 QTableWidget – II wersja
Potencjalnie szybsza. W I wersji kosztowna może być konwersja na QByteArray. W II tworzymy podklasę QMimeData.

29 QTableWidget – II wersja
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; };

30 QTableWidget – II wersja
Przechowujemy wskaźnik do naszej tabeli oraz zakres, czyli zbiór komórek. Ponadto, jak wspomniano powyżej, musimy ponownie zaimplementować funkcje formats() i retrieveData().

31 QTableWidget – II wersja
Przepisujemy i przypisujemy odpowiednie dane. TableMimeData::TableMimeData(const QTableWidget *tableWidget, const QTableWidgetSelectionRange &range) { myTableWidget = tableWidget; myRange = range; myFormats << "text/csv" << "text/html" << "text/plain"; }

32 QTableWidget – II wersja
QStringList TableMimeData::formats() const { return myFormats; }

33 QTableWidget – II wersja
Zwracamy dane w odpowiednim formacie. 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); }

34 QTableWidget – II wersja
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); } else if (event->mimeData()->hasFormat("text/plain")) { QString plainText = event->mimeData()->text(); } QTableWidget::mouseMoveEvent(event);

35 Drag & drop + schowek Znajdziemy pod QApplication::clipboard().
QClipboard posiada metody: setPixmap(), pixmap() setText(), text() setImage(), image() QTextEdit posiada metody: cut() copy() paste()

36 Drag & drop + schowek Czasem nie wystarcza nam zwykły schowek, gdy np. mamy dane nie będące tekstem, ani obrazem. Problem rozwiązujemy podobnie jak przed kilkoma slajdami. Tworzymy podklasę QClipboard i implementujemy odpowiednie metody, np. setMimedata(), mimedata()

37 Drag & drop + schowek Selection Supportowane tylko na X11
Aby uzyskać dostęp do zaznaczonego tekstu należy: sprawdzić czy Selection jest supportowane przekazać w parametrze QClipboard::Selection

38 Drag & drop + schowek void MyTextEditor::mouseReleaseEvent(QMouseEvent *event) { QClipboard *clipboard = QApplication::clipboard(); if (event->button() == Qt::MidButton && clipboard->supportsSelection()) { QString text = clipboard->text(QClipboard::Selection); pasteText(text); }

39 Rozdział 9. Drag and drop. Dziękuje


Pobierz ppt "Seminarium Informatyka Prowadzący dr Grzegorz Wójcik"

Podobne prezentacje


Reklamy Google