PDA

View Full Version : what's the better practice?



xyzt
22nd March 2008, 19:31
I'm working on an example in the QT Documentation,Diagram Scene Example.

In the example, the DiagramItem class is designed for the items to be drawn in to the scene. Different kinds of items(Conditional,Process,Input/Output,Text) exists and these are enumerated in the DiagramItem class and are distinct with switch... But I don't know if it's the best way.Wouldn't it be better if the Conditional,Process,IO,Text items inherits from the DiagramItem class.
here's the code and i want to hear you:


#ifndef DIAGRAMITEM_H
#define DIAGRAMITEM_H

#include <QGraphicsPixmapItem>
#include <QList>

class QPixmap;
class QGraphicsItem;
class QGraphicsScene;
class QTextEdit;
class QGraphicsSceneMouseEvent;
class QMenu;
class QGraphicsSceneContextMenuEvent;
class QPainter;
class QStyleOptionGraphicsItem;
class QWidget;
class QPolygonF;
class Arrow;

class DiagramItem : public QGraphicsPolygonItem
{
public:
enum { Type = UserType + 15 };
enum DiagramType { Step, Conditional, StartEnd, Io };

DiagramItem(DiagramType diagramType, QMenu *contextMenu,
QGraphicsItem *parent = 0, QGraphicsScene *scene = 0);

void removeArrow(Arrow *arrow);
void removeArrows();
DiagramType diagramType() const
{ return myDiagramType; }
QPolygonF polygon() const
{ return myPolygon; }
void addArrow(Arrow *arrow);
QPixmap image() const;
int type() const
{ return Type;}

protected:
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
QVariant itemChange(GraphicsItemChange change, const QVariant &value);

private:
DiagramType myDiagramType;
QPolygonF myPolygon;
QMenu *myContextMenu;
QList<Arrow *> arrows;
};

#endif




#include <QtGui>

#include "diagramitem.h"
#include "arrow.h"

DiagramItem::DiagramItem(DiagramType diagramType, QMenu *contextMenu,
QGraphicsItem *parent, QGraphicsScene *scene)
: QGraphicsPolygonItem(parent, scene)
{
myDiagramType = diagramType;
myContextMenu = contextMenu;

QPainterPath path;
switch (myDiagramType) {
case StartEnd:
path.moveTo(200, 50);
path.arcTo(150, 0, 50, 50, 0, 90);
path.arcTo(50, 0, 50, 50, 90, 90);
path.arcTo(50, 50, 50, 50, 180, 90);
path.arcTo(150, 50, 50, 50, 270, 90);
path.lineTo(200, 25);
myPolygon = path.toFillPolygon();
break;
case Conditional:
myPolygon << QPointF(-100, 0) << QPointF(0, 100)
<< QPointF(100, 0) << QPointF(0, -100)
<< QPointF(-100, 0);
break;
case Step:
myPolygon << QPointF(-100, -100) << QPointF(100, -100)
<< QPointF(100, 100) << QPointF(-100, 100)
<< QPointF(-100, -100);
break;
default:
myPolygon << QPointF(-120, -80) << QPointF(-70, 80)
<< QPointF(120, 80) << QPointF(70, -80)
<< QPointF(-120, -80);
break;
}
setPolygon(myPolygon);
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
}

void DiagramItem::removeArrow(Arrow *arrow)
{
int index = arrows.indexOf(arrow);

if (index != -1)
arrows.removeAt(index);
}

void DiagramItem::removeArrows()
{
foreach (Arrow *arrow, arrows) {
arrow->startItem()->removeArrow(arrow);
arrow->endItem()->removeArrow(arrow);
scene()->removeItem(arrow);
delete arrow;
}
}

void DiagramItem::addArrow(Arrow *arrow)
{
arrows.append(arrow);
}

QPixmap DiagramItem::image() const
{
QPixmap pixmap(250, 250);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setPen(QPen(Qt::black, 8));
painter.translate(125, 125);
painter.drawPolyline(myPolygon);

return pixmap;
}

void DiagramItem::contextMenuEvent(QGraphicsSceneContex tMenuEvent *event)
{
scene()->clearSelection();
setSelected(true);
myContextMenu->exec(event->screenPos());
}

QVariant DiagramItem::itemChange(GraphicsItemChange change,
const QVariant &value)
{
if (change == QGraphicsItem::ItemPositionChange) {
foreach (Arrow *arrow, arrows) {
arrow->updatePosition();
}
}

return value;
}

wysota
22nd March 2008, 19:42
In general it depends. In most cases it'd be better to make each type a separate item class inheriting a common base.