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 <QToolButton> #include <QToolBar> #include <QMimeData> #include <QDrag> #include <QMouseEvent> 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
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); } }
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; }
Funkce addColorButtons prida do “toolbaru” nekolik barevnych tlacitek.
#include "colorbutton.h" #include "colorbutton.h" #include <QPainter> 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); } }
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"); }
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; };
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); } }
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 <QColor> (); // 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); } } }