两个可移动的 QGraphicsRectItem 之间的 QGraphicsPathItem
QGraphicsPathItem between two movable QGraphicsRectItem
我正在尝试关注 this example 和 eyllanesc 的回答
在两个 draggable/movable QGraphicsRectItem
s
之间画一条以箭头结尾的线
这是我的代码:
自定义的QGraphicsPathItem
class(继承自QObject也是因为我用到了signals):
wireArrow.h
public slots:
void changePosStart(QPointF newpos);
void changePosEnd(QPointF newpos);
private:
component *myStartItem;
component *myEndItem;
QPolygonF arrowHead;
QColor myColor = Qt::black;
WireArrow.cpp
WireArrow::WireArrow(component *startItem, component *endItem,
QGraphicsItem *parent )
: QGraphicsPathItem(parent), myStartItem(startItem), myEndItem(endItem)
{
connect(startItem,SIGNAL(componentPosChanged(QPointF)),this, SLOT(changePosStart(QPointF)) );
);
connect(endItem,SIGNAL(componentPosChanged(QPointF)),this,SLOT(changePosEnd(QPointF)) );;
this->setPos(myStartItem->pos());
setFlag(ItemIsSelectable);
setPen(QPen(myColor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
// QPainterPath path;
// path.quadTo(100,0,100,100);
QPainterPath rectPath;
rectPath.moveTo(0.0, 0.0);
rectPath.lineTo(myStartItem->pos().x()-myEndItem->pos().x() , myStartItem->pos().y()-myEndItem->pos().y());
this->setPath(rectPath);
}
void WireArrow::changePosStart(QPointF newpos)
{//@to-do: find how to update pos setpos + this->update maybe? }
void WireArrow::changePosEnd(QPointF newpos)
{//@to-do: find how to update the end pos}
自定义的qgraphicsitem
class(也继承自QObject,在位置更新时发出信号):
component::component(/*some irrelevant params*/QGraphicsItem*parent ):
QGraphicsRectItem(parent), //...init other params
{
setRect(-40, -40, 80, 80);
setFlag(ItemIsMovable);
setFlag(ItemIsSelectable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
}
QVariant component::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange && scene()) {
qDebug() << "cmp:: event change on scene";
QPointF newPos = value.toPointF();
emit componentPosChanged(newPos);
}
return QGraphicsItem::itemChange(change, value);
}
main
// create two components out and in
WireArrow * wa = new WireArrow(out,in);
scene->addItem(wa);
我可以创建矩形(组件)并将它们移动得很好(感谢答案 ,我的问题是我可以从 out
绘制线条 origination 但是:
- 我无法正确地从一个组件绘制到另一个组件。
- 我需要让它们在拖动矩形时自动移动。在其他示例中,我看到他们将线条视为
项目,这是我不能在这里做的事情,因为电线是两个人用的
项目而不是一个所以我用 signal/slot 连接替换了它但是
我仍然不知道如何更新位置...
解释我正在尝试做的事情的图像
(方块真的是用qt画的,线是paint画的,方块是可以动的)
简而言之:只是试图在两点(两个方块的位置)之间画一条线,并且这些方块是可移动的,所以如果两个方块之一移动,该线应该适应。
所要求的与我在 so I will limit the code translated from python to c++中实现的非常相似:
component.h
#ifndef COMPONENT_H
#define COMPONENT_H
#include <QGraphicsRectItem>
class Arrow;
class Component : public QGraphicsRectItem
{
public:
Component(QGraphicsItem *parent = nullptr);
void addArrow(Arrow *arrow);
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
private:
QVector<Arrow *> mArrows;
};
#endif // COMPONENT_H
component.cpp
#include "arrow.h"
#include "component.h"
Component::Component(QGraphicsItem *parent):
QGraphicsRectItem(parent)
{
setRect(-40, -40, 80, 80);
setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemSendsGeometryChanges);
}
void Component::addArrow(Arrow *arrow)
{
mArrows << arrow;
}
QVariant Component::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if(change == QGraphicsItem::ItemPositionHasChanged){
for(Arrow * arrow: qAsConst(mArrows)){
arrow->adjust();
}
}
return QGraphicsRectItem::itemChange(change, value);
}
arrow.h
#ifndef ARROW_H
#define ARROW_H
#include <QGraphicsPathItem>
class Component;
class Arrow : public QGraphicsPathItem
{
public:
Arrow(Component *startItem, Component *endItem, QGraphicsItem *parent = nullptr);
void adjust();
private:
Component *mStartItem;
Component *mEndItem;
};
#endif // ARROW_H
arrow.cpp
#include "arrow.h"
#include "component.h"
#include <QPen>
Arrow::Arrow(Component *startItem, Component *endItem, QGraphicsItem *parent):
QGraphicsPathItem(parent), mStartItem(startItem), mEndItem(endItem)
{
mStartItem->addArrow(this);
mEndItem->addArrow(this);
setPen(QPen(QColor("red"), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
adjust();
}
void Arrow::adjust()
{
prepareGeometryChange();
QPainterPath path;
path.moveTo(mStartItem->pos());
path.lineTo(mEndItem->pos());
setPath(path);
}
Component *comp1 = new Component;
Component *comp2 = new Component;
comp1->setPos(50, 50);
comp2->setPos(400, 400);
Arrow *arrow = new Arrow(comp1, comp2);
scene->addItem(comp1);
scene->addItem(comp2);
scene->addItem(arrow);
我正在尝试关注 this example 和 eyllanesc 的回答
QGraphicsRectItem
s
这是我的代码:
自定义的QGraphicsPathItem
class(继承自QObject也是因为我用到了signals):
wireArrow.h
public slots:
void changePosStart(QPointF newpos);
void changePosEnd(QPointF newpos);
private:
component *myStartItem;
component *myEndItem;
QPolygonF arrowHead;
QColor myColor = Qt::black;
WireArrow.cpp
WireArrow::WireArrow(component *startItem, component *endItem,
QGraphicsItem *parent )
: QGraphicsPathItem(parent), myStartItem(startItem), myEndItem(endItem)
{
connect(startItem,SIGNAL(componentPosChanged(QPointF)),this, SLOT(changePosStart(QPointF)) );
);
connect(endItem,SIGNAL(componentPosChanged(QPointF)),this,SLOT(changePosEnd(QPointF)) );;
this->setPos(myStartItem->pos());
setFlag(ItemIsSelectable);
setPen(QPen(myColor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
// QPainterPath path;
// path.quadTo(100,0,100,100);
QPainterPath rectPath;
rectPath.moveTo(0.0, 0.0);
rectPath.lineTo(myStartItem->pos().x()-myEndItem->pos().x() , myStartItem->pos().y()-myEndItem->pos().y());
this->setPath(rectPath);
}
void WireArrow::changePosStart(QPointF newpos)
{//@to-do: find how to update pos setpos + this->update maybe? }
void WireArrow::changePosEnd(QPointF newpos)
{//@to-do: find how to update the end pos}
自定义的qgraphicsitem
class(也继承自QObject,在位置更新时发出信号):
component::component(/*some irrelevant params*/QGraphicsItem*parent ):
QGraphicsRectItem(parent), //...init other params
{
setRect(-40, -40, 80, 80);
setFlag(ItemIsMovable);
setFlag(ItemIsSelectable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
}
QVariant component::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange && scene()) {
qDebug() << "cmp:: event change on scene";
QPointF newPos = value.toPointF();
emit componentPosChanged(newPos);
}
return QGraphicsItem::itemChange(change, value);
}
main
// create two components out and in
WireArrow * wa = new WireArrow(out,in);
scene->addItem(wa);
我可以创建矩形(组件)并将它们移动得很好(感谢答案 out
绘制线条 origination 但是:
- 我无法正确地从一个组件绘制到另一个组件。
- 我需要让它们在拖动矩形时自动移动。在其他示例中,我看到他们将线条视为 项目,这是我不能在这里做的事情,因为电线是两个人用的 项目而不是一个所以我用 signal/slot 连接替换了它但是 我仍然不知道如何更新位置...
解释我正在尝试做的事情的图像
(方块真的是用qt画的,线是paint画的,方块是可以动的)
简而言之:只是试图在两点(两个方块的位置)之间画一条线,并且这些方块是可移动的,所以如果两个方块之一移动,该线应该适应。
所要求的与我在
component.h
#ifndef COMPONENT_H
#define COMPONENT_H
#include <QGraphicsRectItem>
class Arrow;
class Component : public QGraphicsRectItem
{
public:
Component(QGraphicsItem *parent = nullptr);
void addArrow(Arrow *arrow);
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
private:
QVector<Arrow *> mArrows;
};
#endif // COMPONENT_H
component.cpp
#include "arrow.h"
#include "component.h"
Component::Component(QGraphicsItem *parent):
QGraphicsRectItem(parent)
{
setRect(-40, -40, 80, 80);
setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemSendsGeometryChanges);
}
void Component::addArrow(Arrow *arrow)
{
mArrows << arrow;
}
QVariant Component::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if(change == QGraphicsItem::ItemPositionHasChanged){
for(Arrow * arrow: qAsConst(mArrows)){
arrow->adjust();
}
}
return QGraphicsRectItem::itemChange(change, value);
}
arrow.h
#ifndef ARROW_H
#define ARROW_H
#include <QGraphicsPathItem>
class Component;
class Arrow : public QGraphicsPathItem
{
public:
Arrow(Component *startItem, Component *endItem, QGraphicsItem *parent = nullptr);
void adjust();
private:
Component *mStartItem;
Component *mEndItem;
};
#endif // ARROW_H
arrow.cpp
#include "arrow.h"
#include "component.h"
#include <QPen>
Arrow::Arrow(Component *startItem, Component *endItem, QGraphicsItem *parent):
QGraphicsPathItem(parent), mStartItem(startItem), mEndItem(endItem)
{
mStartItem->addArrow(this);
mEndItem->addArrow(this);
setPen(QPen(QColor("red"), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
adjust();
}
void Arrow::adjust()
{
prepareGeometryChange();
QPainterPath path;
path.moveTo(mStartItem->pos());
path.lineTo(mEndItem->pos());
setPath(path);
}
Component *comp1 = new Component;
Component *comp2 = new Component;
comp1->setPos(50, 50);
comp2->setPos(400, 400);
Arrow *arrow = new Arrow(comp1, comp2);
scene->addItem(comp1);
scene->addItem(comp2);
scene->addItem(arrow);