Drag And Drop - barevná tlačítka

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 <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

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

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 <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);
           }
    }
}
 
qt/graphics_color_button_xml.txt · Last modified: 2021/03/24 13:14 by 88.103.111.44
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki