===== Drag And Drop - barevná tlačítka ===== {{qt:colorbuttons.png}} ==== Třída ColorButton ==== Vytvorime tridu **ColorButton** odvozenou z **QToolButton**. \\ (Qt Creator : pravou mysi na graphics v projektovem stromu, Add New / C++ Class ) V teto tride predefinujeme virtualni metody **mousePressEvent.** \\ ( Qt Creator : mysi na class ColorButton, prave tlacitko mysi, Refactor / Insert Virtual Functions. ) #ifndef COLORBUTTON_H #define COLORBUTTON_H #include #include #include #include #include class ColorButton : public QToolButton { private: QColor color; QString name; QPixmap getPixmap (); protected: void mousePressEvent (QMouseEvent *event); public: ColorButton (QColor p_color, QString p_name = ""); }; void addColorButtons (QToolBar * page); #endif // COLORBUTTON_H ==== Reakce na stisknutí myši ==== Vytvoříme nový objekt typu **QMimeData**. \\ Metodou **setColorData** vložíme barvu. ( Pomoci **setText** muzete pridat i nejaka textova data, ** mimeData->setText (name); ** a zkusit drag a drop do textoveho editoru. ) Vytvoříme nový objekt typu **QDrag**. \\ Do drag objektu uložíme **mimeData**. \\ Přidáme obrázek, který bude zobrazován spolu s kurzorem myši při tažení myši. \\ Obrázek mírně posuneme dále od kurzoru. Metodou **drag->exec()** zahájíme drag and drop. void ColorButton::mousePressEvent (QMouseEvent * event) { if (event->button() == Qt::LeftButton ) { QMimeData * mimeData = new QMimeData; mimeData->setColorData (color); QDrag * drag = new QDrag (this); drag->setMimeData (mimeData); drag->setPixmap (getPixmap ()); drag->setHotSpot (QPoint (-16, -16)); Qt::DropAction dropAction = drag->exec (Qt::MoveAction | Qt::CopyAction | Qt::LinkAction); } } ==== Barevný puntík ==== Funkce **getPixmap** vraci objekt typu **QPixmap** (primo QPixmap, neni zde ukazatel). \\ Tuto funkci pouzijeme take v konstruktoru tridy: ** setIcon (getPixmap ()) ** Vytvorime objekt **pixmap** typu **QPixmap**, konstruktoru predame velikost (12, 12). \\ Obrazek vyplnime //"pruhlednou barvou"//. K objektu **pixmap** pripojime objekt **painter** typu **QPainter**. \\ V paiteru nastavime //"stetec"// s barvou naseho tlacitka. \\ Nakreslime maly krouzek. QPixmap ColorButton::getPixmap () { QPixmap pixmap (12, 12); pixmap.fill (Qt::transparent); QPainter painter (&pixmap); painter.setPen (Qt::NoPen); painter.setBrush (QBrush (color)); painter.drawEllipse (0, 0, 12, 12); painter.end (); return pixmap; } ==== Implementace třídy ColorButton ==== Funkce **addColorButtons** prida do //"toolbaru"// nekolik barevnych tlacitek. #include "colorbutton.h" #include "colorbutton.h" #include ColorButton::ColorButton(QColor p_color, QString p_name) : color (p_color), name (p_name) { setIcon (getPixmap ()); setToolTip (name); } QPixmap ColorButton::getPixmap () { QPixmap pixmap (12, 12); pixmap.fill (Qt::transparent); QPainter painter (&pixmap); painter.setPen (Qt::NoPen); painter.setBrush (QBrush (color)); painter.drawEllipse (0, 0, 12, 12); painter.end (); return pixmap; } void ColorButton::mousePressEvent (QMouseEvent * event) { if (event->button() == Qt::LeftButton ) { QMimeData * mimeData = new QMimeData; mimeData->setColorData (color); QDrag * drag = new QDrag (this); drag->setMimeData (mimeData); drag->setPixmap (getPixmap ()); drag->setHotSpot (QPoint (-16, -16)); Qt::DropAction dropAction = drag->exec (Qt::MoveAction | Qt::CopyAction | Qt::LinkAction); } } ==== Několik barevných tlačítek ==== Funkce **addColorButtons** prida do //"toolbaru"// nekolik barevnych tlacitek. void addColorButton (QToolBar * page, QString name) { ColorButton * b = new ColorButton (QColor (name), name); page->addWidget (b); } void addColorButtons (QToolBar * page) { addColorButton (page, "red"); addColorButton (page, "blue"); addColorButton (page, "green"); addColorButton (page, "yellow"); addColorButton (page, "orange"); addColorButton (page, "silver"); addColorButton (page, "gold"); addColorButton (page, "goldenrod"); addColorButton (page, "lime"); addColorButton (page, "lime green"); addColorButton (page, "yellow green"); addColorButton (page, "green yellow"); addColorButton (page, "forest green"); addColorButton (page, "coral"); addColorButton (page, "cornflower blue"); addColorButton (page, "dodger blue"); addColorButton (page, "royal blue"); addColorButton (page, "wheat"); addColorButton (page, "chocolate"); addColorButton (page, "peru"); addColorButton (page, "sienna"); addColorButton (page, "brown"); } ==== Drop === Vytvorime si tridu **Scene** odvozenou z **QGraphicsScene**. \\ ( zdrojove texty //view.h// a //view.cc//, pouziti v konstruktoru tridy **mainWindow** v //demo.cc// \\ Predefinujeme nekolik metod class Scene : public QGraphicsScene { protected: virtual void dragEnterEvent (QGraphicsSceneDragDropEvent * event) override; virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event) override; virtual void dropEvent (QGraphicsSceneDragDropEvent * event) override; }; === Reakce na pohyb myši s taženými daty === Pri prichodu mysi je zavolana metods **dragEnterEvent**. \\ Prevezmeme skupinu prenasenych dat **mimeData**. \\ Pokud v teto skupine jsou i barevna data, souhlasim s //"drop"//. void Scene::dragEnterEvent (QGraphicsSceneDragDropEvent * event) { const QMimeData * mimeData = event->mimeData(); if (mimeData->hasColor()) { event->setAccepted (true); } else { event->setAccepted (false); } } V pripade graficke sceny take musime reagovat na pohyb mysi nad scenou. http://stackoverflow.com/questions/4177720/accepting-drops-on-a-qgraphicsscene void Scene::dragMoveEvent (QGraphicsSceneDragDropEvent *event) { const QMimeData * mimeData = event->mimeData(); if (mimeData->hasColor()) { event->setAccepted (true); } else { event->setAccepted (false); } } === Reakce na vhození dat === Z **mimeData** vyzvedneme **color**. \\ Behem ladeni alespon nakreslime barevnou usecku. Nalezneme **item** nad kterym je prave mys. \\ Pokusime se pretypovat na **shape** (ktery ma metody setPen a setBrush) Pokud uzivatel behem //drag and drop// stisknul //ctrl// nastavime barvu okraje vybraneho prvku. \\ Nebo nastavime barvu vnitrku. void Scene::dropEvent (QGraphicsSceneDragDropEvent * event) { const QMimeData * mimeData = event->mimeData(); if (mimeData->hasColor()) { QColor color = mimeData->colorData().value (); // addLine (0, 0, 100, 200, color); QGraphicsItem * item = itemAt (event->scenePos (), QTransform ()); // do not use event->pos() QAbstractGraphicsShapeItem * shape = dynamic_cast < QAbstractGraphicsShapeItem * > (item); if (shape != nullptr) { if (event->proposedAction() == Qt::CopyAction) /* ctrl */ shape->setPen (color); else shape->setBrush (color); } } }