Qt의 전체 QGraphics 및 QGraphicsScene을 알게되었습니다. 이제 저는 베니어 곡선을 관리하는 프로그램을 만들려고합니다 (동체 섹션을 모델링하기 위해 코드에 "섹션"이있는 이유입니다).Qt QGraphicsScene 항목() 세분화 오류
구현 QGraphicsScene
클래스 :
class SectionScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit SectionScene(Database* database, QObject *parent = 0);
BezierCurve* currentCurve();
signals:
public slots:
void focusCurve(BezierCurve* curve);
void addNode(BezierNode* node);
private:
void mousePressEvent(QGraphicsSceneMouseEvent* e);
Database* database;
BezierCurve* m_currentCurve;
QPainter* painter;
};
SectionScene::SectionScene(Database* database, QObject *parent) :
QGraphicsScene(parent)
{
this->database = database;
this->setSceneRect(-100,-100,200,200);
connect(database,SIGNAL(curveFocus(BezierCurve*)),this,SLOT(focusCurve(BezierCurve*)));
connect(database,SIGNAL(nodeAdd(BezierNode*)),this,SLOT(addNode(BezierNode*)));
painter = new QPainter();
addItem(new QGraphicsRectItem(QRectF(0,0,100,100)));
}
void SectionScene::addNode(BezierNode *node)
{
addItem(node);
if (node->leftControlPoint()) addItem(node->leftControlPoint());
if (node->rightControlPoint()) addItem(node->rightControlPoint());
update();
}
void SectionScene::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
if (e->button() == Qt::LeftButton && e->modifiers() == Qt::ControlModifier) {
BezierNode* node = new BezierNode(e->scenePos());
currentCurve()->appendNode(node);
} else {
if (items(e->scenePos()).size()) {
QGraphicsScene::mousePressEvent(e);
}
}
}
그리고 BezierNode
클래스, QGraphicsItem
입니다 :
class BezierNode : public QGraphicsItem
{
Q_INTERFACES(QGraphicsItem)
public:
enum Type {Symmetric, Smooth, Angular};
BezierNode(QPointF point = QPointF(0,0), Type type = Symmetric);
void setPoint(QPointF point);
QPointF& point();
void setLeftControlPoint(BezierControlPoint*);
BezierControlPoint* leftControlPoint();
void setRightControlPoint(BezierControlPoint*);
BezierControlPoint* rightControlPoint();
void setType(Type);
Type type();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QPainterPath shape() const;
public slots:
// void mousePressEvent(QGraphicsSceneMouseEvent *event);
// void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
bool sceneEvent(QEvent *event);
private:
QPointF m_point;
BezierControlPoint* m_leftControlPoint;
BezierControlPoint* m_rightControlPoint;
Type m_type;
bool m_selected = false;
bool m_hovered = false;
};
BezierNode::BezierNode(QPointF point, Type type) : QGraphicsItem()
{
m_point = point;
m_type = type;
if (type == Symmetric) {
BezierControlPoint* leftControlPoint = new BezierControlPoint(point - QPoint(30,0),this);
BezierControlPoint* rightControlPoint = new BezierControlPoint(point + QPoint(30,0),this);
setLeftControlPoint(leftControlPoint);
setRightControlPoint(rightControlPoint);
}
// setFlags(ItemIsMovable);
}
QRectF BezierNode::boundingRect() const
{
qreal size = 7;
QPointF topLeft = m_point - QPointF(size,-size);
QPointF bottomRight = m_point + QPointF(size, -size);
return QRectF(topLeft,bottomRight);
}
void BezierNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->drawEllipse(boundingRect());
}
QPainterPath BezierNode::shape() const
{
QPainterPath path;
path.addEllipse(boundingRect());
}
mousePressEvent
에 SectionScene
행동하는 것은 다음입니다 : 제대로 BezierNode
를 만들고 그것을 그립니다 Ctrl 키 수정과 함께 보기 (단 하나의보기 만 사용됨, 장면이 묶여 있음). 수식어가없는 왼쪽 클릭이있는 경우 BezierNode
바깥 쪽을 클릭하면 모든 것이 괜찮습니다. 하지만 클릭하면 items(e->scenePos())
에 세분화 오류가 발생합니다. 동일한 것은 itemAt(..)
이었고 나는 단지 QGraphicsScene::mousePressEvent(e)
만 시도했을 때였습니다. 몇 시간 동안 지나갈 수 없으므로 나는 당신의 생각을 듣고 싶습니다. 또한 (BezierNode
)은이 항목과 관련이 없더라도 모든 장면 이벤트에서 트리거됩니다. 그것이 어떻게되어야 하는가?
전체 컴파일 가능한 프로젝트는 git에서 찾을 수 있습니다.
디버거가'items (..) '의 소유자가'e '인수가 null이라고 말합니까? – cmannett85
@morodeer 컴파일러에서 경고를 켜야합니다. 'QPainterPath BezierNode :: shape()'를 반환하지 않는 리턴 타입을 가진 많은 함수가 있습니다. – PeterT
@PeterT, 감사합니다! 다른 경고들 중에서 그것을 잃어 버렸고, 내 머리를 완전히 벗었습니다. 'shape()'에 반환 값을 더하는 것이 도움이되었습니다. – ProdoElmit