===== 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);
}
}
}