我正在尝试重新设计我的项目类。我无法想象事情应该如何运作。
当前实施:
function linked_node = find_neighbours(N, M, CONNECTED)
%# which distance function
if CONNECTED == 8
distFunc = 'chebychev';
else
distFunc = 'cityblock';
end
linked_node=cell(N*M,1);
% the most important step
for X=1:N
for Y=1:M
linked_node{sub2ind([N M], X,Y)} = [];
if X - 1 > 0
linked_node{sub2ind([N M], X,Y)}(end+1) = sub2ind([N M], X-1,Y);
if strcmp(distFunc, 'chebychev')
if Y - 1 > 0
linked_node{sub2ind([N M], X,Y)}(end+1) = sub2ind([N M], X-1,Y-1);
end
if Y + 1 <= M
linked_node{sub2ind([N M], X,Y)}(end+1) = sub2ind([N M], X-1,Y+1);
end
end
end
if X + 1 <= N
linked_node{sub2ind([N M], X,Y)}(end+1) = sub2ind([N M], X+1,Y);
if strcmp(distFunc, 'chebychev')
if Y - 1 > 0
linked_node{sub2ind([N M], X,Y)}(end+1) = sub2ind([N M], X+1,Y-1);
end
if Y + 1 <= M
linked_node{sub2ind([N M], X,Y)}(end+1) = sub2ind([N M], X+1,Y+1);
end
end
end
if Y - 1 > 0
linked_node{sub2ind([N M], X,Y)}(end+1) = sub2ind([N M], X,Y-1);
end
if Y + 1 <= M
linked_node{sub2ind([N M], X,Y)}(end+1) = sub2ind([N M], X,Y+1);
end
end
end
end
根据选择,我创建一个项目并添加到画布......然后,一旦完成所有更改,我将其添加到class Item : public QGraphicsItem
{
public:
typedef enum { PolygonType = QGraphicsItem::UserType + 1 } ShapeType;
Item() {...}
Item(const Item ©Item) // copy constructor
{ m_shapeType = copyItem.getItemShape();
m_color = copyItem.getItemColor();
setPos(copyItem.pos()); ...}
QRectF boundingRect() const;
QPainterPath shape() const;
void setItemShape(ShapeType s) { m_shapeType = s; }
ShapeType getItemShape() const { return m_shapeType; }
int type() const { return m_shapeType; } // this will replace the above to allow QGraphicsItem casts
void setItemColor(QColor c) { m_color = c; }
QColor getItemColor() const { return m_color; }
....
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
QColor m_color;
ShapeType m_shapeType;
....
};
QPainterPath Item::shape() const
{
QPainterPath path;
switch (m_shapeType)
{
case Item::PolygonType:
...
break;
....
}
}
QRectF Item::boundingRect() const
{
return QRectF(...);
}
void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
{
switch (m_shapeType)
{
case Item::PolygonType:
painter->drawPolygon(shape().toFillPolygon());
break;
....
}
}
。
所需任务:
场景的处理包含类型
的迭代QGraphicsScene
我想要实现的目标
这是一种最小的方法,但我必须将功能扩展到扩展其他类的项目,例如Item* item1 = new Item(*renderArea->item);
// make some changes on the item copy, then add it to a scene
collectionView->scene()->addItem(item1);
// in another function...
for(int i = 0; i < collectionView->scene()->items().size(); ++i)
{
Item* item = new Item(*(dynamic_cast<Item*>(
collectionView->scene()->items().at(i))));
...
}
(无需为每个不需要它的项添加像素图)或QGraphicsPixmapItem
(同样,无需为不需要它的项目添加太多开销)。
所以我在尝试:
QGraphicsSvgItem
或
class PolyItem : public Item
{
public:
PolyItem(): Item()
{
m_shapeType = Item::PolygonType;
}
PolyItem(PolyItem& copy): Item::Item(copy)
{
}
virtual void paint(QPainter* painter,
const QStyleOptionGraphicsItem* option,
QWidget* widget = NULL)
{
painter->drawPolygon(shape().toFillPolygon());
}
};
问题:
- - - - &GT;我想在类Item中创建一个不同的构造函数来创建正确的形状 - 但这似乎意味着Item需要类多边形,需要类Item ...循环依赖?
我无法想象:
class PixMapItem : public Item, public QGraphicsPixmapItem
{
public:
PixMapItem(): Item()
{
m_shapeType = Item::PixmapType;
setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
}
PixMapItem(PixMapItem& copy): Item::Item(copy)
{
setPixmap(copy.pixmap());
setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
}
virtual void paint(QPainter* painter,
const QStyleOptionGraphicsItem* option,
QWidget* widget = NULL)
{
painter->drawPixmap(boundingRect(), pixmap());
}
};
如果我的项目是多边形类型,是否会调用collectionView->scene()->addItem(item1);
函数 - 以及所有其他相关函数 - 或Item::paint()
?
我是否必须插入switch-case代码来确定和转换每个类型的每个实例?
答案 0 :(得分:1)
根据运行时决策创建不同的对象是Abstract factory pattern的典型用例。在您的情况下,您可以:
class ItemFactory
{
public:
virtual Item* create() = 0;
};
然后:
class PixMapItemFactory : public ItemFactory
{
public:
PixMapItemFactory(/* possibly some configuration parameters */);
Item* create(); // will return a PixMapItem instance
};
然后您可以操作ItemFactory*
类型,不知道也不关心您正在创建的特定类型。它将返回Item*
个实例,因此无论具体实例类型如何,您都可以更改它们的公共属性。