[[qt_xml]]
 
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QTreeWidgetItem>
#include <QToolButton>
 
#include <QGraphicsScene>
#include <QAbstractGraphicsShapeItem>
#include <QGraphicsRectItem>
#include <QGraphicsEllipseItem>
 
#include <QTableWidgetItem>
 
namespace Ui {
class MainWindow;
}
 
class ParamList : public QMap <QString, QString>
{
   public:
      int number (QString key, int default_value = 0);
};
 
class ColorButton : public QToolButton
{
private :
    QString name;
    QColor color;
public :
    ColorButton (QString s);
protected:
    void mousePressEvent(QMouseEvent *event);
};
 
class Common : private QObject
{
Q_OBJECT
public :
    ParamList params;
};
 
class Rectangle : public QGraphicsRectItem, public Common
{
protected:
    void dragEnterEvent (QGraphicsSceneDragDropEvent *event);
    void dropEvent (QGraphicsSceneDragDropEvent *event);
public:
    Rectangle ();
};
 
class Ellipse : public QGraphicsEllipseItem, public Common
{
protected:
    void dragEnterEvent (QGraphicsSceneDragDropEvent *event);
    void dropEvent (QGraphicsSceneDragDropEvent *event);
public:
    Ellipse ();
};
 
 
class TreeNode : public QTreeWidgetItem
{
public:
    Common * common;
    QAbstractGraphicsShapeItem * shape;
    TreeNode () : common (NULL), shape (NULL) { }
};
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
 
    void readFile(QString fileName);
 
    Rectangle * createRectangle (TreeNode * node,
                                 QGraphicsItem * target,
                                 ParamList param);
 
    Ellipse * createEllipse (TreeNode * node,
                             QGraphicsItem * target,
                             ParamList param);
 
    void modifyShape (QGraphicsItem * target,
                      QAbstractGraphicsShapeItem * shape,
                      ParamList param);
 
private slots:
    void on_treeWidget_itemClicked(QTreeWidgetItem *item, int column);
 
    void on_tableWidget_itemChanged(QTableWidgetItem *item);
 
private:
    Ui::MainWindow * ui;
    QGraphicsScene * scene;
    Common * current_element;
};
 
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
#include <QFile>
#include <QXmlStreamReader>
#include <QXmlStreamAttribute>
 
#include <QDrag>
#include <QMimeData>
#include <QIcon>
#include <QGraphicsSceneDragDropEvent>
 
int ParamList::number(QString key, int default_value)
{
    QString s = this->value (key);
    bool ok;
    int n = s.toInt (&ok);
    if (!ok)
        n = default_value;
    return n;
}
 
/* Color Button */
 
ColorButton::ColorButton(QString s)
  : name (s), color (QColor (s))
{
    setText (s);
    setToolTip (s);
 
    QPixmap p (24, 24);
    p.fill (QColor (0, 0, 0, 0));
 
    QPainter m (&p);
    m.setPen (color);
    m.setBrush (color);
    m.drawEllipse (2, 2, 20, 20);
 
    QIcon icon (p);
    setIcon (icon);
}
 
void ColorButton::mousePressEvent(QMouseEvent *event)
{
    QDrag * drag = new QDrag (this);
    QMimeData * data = new QMimeData ();
    data->setText (name);
    data->setColorData (color);
    drag->setMimeData(data);
 
    QPixmap p = this->icon().pixmap(12, 12);
    drag->setPixmap(p);
 
    drag->start(Qt::CopyAction | Qt::MoveAction);
};
 
/* Rectangle */
 
void Rectangle::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
    event->setAccepted(true);
}
 
void Rectangle::dropEvent(QGraphicsSceneDragDropEvent *event)
{
   const QMimeData * data =  event->mimeData();
   if (data->hasColor())
   {
       QColor c =  data->colorData().value <QColor> ();
       if (event->proposedAction() == Qt::MoveAction) /* shift */
          setPen (c);
       else
          setBrush (c);
   }
}
 
Rectangle::Rectangle()
{
    setAcceptDrops(true);
}
 
/* Ellipse */
 
void Ellipse::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
    event->setAccepted(true);
}
 
void Ellipse::dropEvent(QGraphicsSceneDragDropEvent *event)
{
   const QMimeData * data =  event->mimeData();
   if (data->hasColor())
   {
       QColor c =  data->colorData().value <QColor> ();
       if (event->proposedAction() == Qt::MoveAction) /* shift */
          setPen (c);
       else
          setBrush (c);
   }
}
 
Ellipse::Ellipse()
{
    setAcceptDrops(true);
}
 
/* MainWindow */
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    current_element (NULL)
 
{
    ui->setupUi(this);
 
    QList <QString> names;
    names << "red" << "blue" << "green" << "yellow" << "orange";
 
    for (auto name : names)
    {
       ColorButton * b = new ColorButton (name);
       ui->mainToolBar->addWidget (b);
    }
 
    scene = new QGraphicsScene;
    ui->graphicsView->setScene (scene);
 
    // scene->addLine (0, 0, 100, 100, QColor ("blue"));
    scene->setSceneRect (0, 0, 1024, 800);
 
    readFile ("../xml/data.xml");
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::readFile (QString fileName)
{
    QFile file (fileName);
    if (file.open (QFile::ReadOnly | QFile::Text ))
    {
        QTreeWidgetItem * branch =
                ui->treeWidget->invisibleRootItem();
 
        QGraphicsItem * target = NULL;
 
        QXmlStreamReader reader (&file);
        while (! reader.atEnd())
        {
            if (reader.isStartElement())
            {
                QString s = reader.name().toString();
                TreeNode * item = new TreeNode;
                item->setText (0, s);
                item->setForeground (0, QColor ("blue"));
                branch->addChild (item);
                branch = item;
 
                ParamList list;
                // for (QXmlStreamAttribute a : reader.attributes())
                for (auto a : reader.attributes())
                {
                   QString t = a.name().toString();
                   QString v = a.value().toString();
                   /*
                   auto node = new QTreeWidgetItem;
                   node->setText (0, t + " = " + v);
                   node->setForeground (0, QColor ("green"));
                   item->addChild (node);
                   */
 
                   // list.insert(t, v);
                   list [t] = v;
                }
 
                if (s == "rectangle")
                   target = createRectangle (item, target, list);
                else if (s == "ellipse")
                   target = createEllipse (item, target, list);
            }
            else if (reader.isCharacters())
            {
                QString s = reader.text().toString().simplified();
                if (s != "")
                {
                   QTreeWidgetItem * item = new QTreeWidgetItem;
                   item->setText (0, s);
                   item->setForeground (0, QColor ("orange"));
                   branch->addChild (item);
                }
            }
            else if (reader.isEndElement())
            {
                branch = branch->parent();
 
                QString s = reader.name().toString();
                if (s == "rectangle" || s == "ellipse")
                   target = target->parentItem ();
            }
            reader.readNext();
        }
        ui->treeWidget->expandAll();
    }
}
 
Rectangle * MainWindow::createRectangle
                        (TreeNode * node,
                         QGraphicsItem * target,
                         ParamList list)
{
    Rectangle * shape = new Rectangle;
 
    shape->params = list;
 
    node->common = shape;
    node->shape = shape;
 
    int w = list.number ("w", 100);
    int h = list.number ("h", 40);
 
    shape->setRect (0, 0, w, h);
 
 
    modifyShape (target, shape, list);
 
    return shape;
}
 
Ellipse * MainWindow::createEllipse
                      (TreeNode * node,
                       QGraphicsItem * target,
                       ParamList list)
{
    Ellipse * shape = new Ellipse;
 
    shape->params = list;
 
    node->common = shape;
    node->shape = shape;
 
    int w = list.number ("w", 10);
    int h = list.number ("h", 10);
 
    shape->setRect (0, 0, w, h);
 
 
    modifyShape (target, shape, list);
 
    return shape;
}
 
void MainWindow::modifyShape (QGraphicsItem * target,
                              QAbstractGraphicsShapeItem * shape,
                              ParamList list)
{
    int x = list.number ("x", 20);
    int y = list.number ("y", 20);
    shape->setPos (x, y);
 
    QString pen = list ["pen"];
    if (pen != "")
       shape->setPen (QColor (pen));
 
    QString brush = list ["brush"];
    if (brush != "")
       shape->setBrush (QColor (brush));
 
    shape->setFlag (QGraphicsItem::ItemIsMovable);
    shape->setFlag (QGraphicsItem::ItemIsSelectable);
 
    if (target == NULL)
       scene->addItem (shape);
    else
       shape->setParentItem (target);
}
 
 
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
{
    TreeNode * node = dynamic_cast <TreeNode*> (item);
    if (node != NULL && node->common != NULL )
    {
        current_element = NULL;
 
        ui->statusBar->showMessage ("click");
 
        ui->tableWidget->clear ();
        ui->tableWidget->setColumnCount (2);
 
        int cnt = 0;
        QMapIterator <QString, QString> iter (node->common->params);
        while (iter.hasNext())
        {
            iter.next();
            QString name = iter.key ();
            QString value = iter.value ();
 
            ui->tableWidget->setRowCount(cnt+1);
 
            QTableWidgetItem * field = new QTableWidgetItem;
            field->setText (name);
            ui->tableWidget->setItem (cnt, 0, field);
 
            field = new QTableWidgetItem;
            field->setText (value);
            ui->tableWidget->setItem (cnt, 1, field);
            if (name == "pen" or name == "brush")
                field->setData(Qt::DecorationRole, QColor (value));
            field->setData(Qt::UserRole, name);
 
            cnt ++;
        }
 
        current_element = node->common;
    }
}
 
int conv (QString s, int default_value)
{
    bool ok;
    int n = s.toInt (&ok);
    if (!ok)
        n = default_value;
    return n;
}
 
void MainWindow::on_tableWidget_itemChanged(QTableWidgetItem *item)
{
    QString name = item->data (Qt::UserRole).toString ();
    QString value = item->text ();
    if (name != "" && current_element != NULL)
    {
       ui->statusBar->showMessage ("update " + name + " = " + value);
 
       Common * common = current_element;
       QAbstractGraphicsShapeItem * shape =
               dynamic_cast <QAbstractGraphicsShapeItem *> (common);
 
       if (name == "pen" && shape != NULL)
           shape->setPen (QColor (value));
 
       if (name == "brush" && shape != NULL)
           shape->setBrush (QColor (value));
 
       if (name == "pen" || name == "brush")
           item->setData(Qt::DecorationRole, QColor (value));
 
       if (name == "x")
           shape->setX (conv (value, 0));
 
       if (name == "y")
           shape->setY (conv (value, 0));
 
       if (name == "w" || name == "h")
       {
           Rectangle * r = dynamic_cast <Rectangle*> (shape);
           Ellipse * e = dynamic_cast <Ellipse*> (shape);
           QRectF size;
           if (r != NULL) size = r->rect();
           if (e != NULL) size = e->rect();
 
           int v = conv (value, 20);
           if (name == "w")
              size.setWidth (v);
           else
              size.setHeight (v);
 
           if (r != NULL) r->setRect (size);
           if (e != NULL) e->setRect (size);
       }
 
       common->params[name] = value;
    }
}
 
qt_xml.txt · Last modified: 2017/04/10 17:01 by 147.32.8.115
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki