[Qt-interest] Qt object initialisation list problem
Andy Bolsover
andybolsover at yahoo.co.uk
Thu Nov 18 23:44:28 CET 2010
I have a small test program to draw a Bezier curve with 2 end points and 2
control points (Controller objects). The Controller objects can be dragged
by the mouse to change the shape of the Bezier curve. I have a
QGraphicsScene and QGraphicsView - the Bezier curve is drawn using code as
follows
Bezier *bez = new Bezier(QPointF(0,100), QPointF(0,0),
QPointF(100,0), QPointF(100,100));
scene->addItem(bez);
bez->setPos(0, 0);
bez->updateCurve();
The Bezier constructor receives four QPointF which are stored in private
variables.
These QPointF are also used to initialise the locations of the four
Controller objects
If I use the passed-in QPointF directly to set positions of the Controller
objects everything is ok,
But if I use the private variables to set positions of the Controller
objects the initial locations are wrong and the private variables are also
altered.
As a result the Bezier curve is the wrong shape when first drawn
I have been looking at this for long enough without seeing what is going
wrong.
I thought it was a C++ problem at first - not Qt, but the problem goes away
when I simplify the test program by removing the Qt
Any suggestions on what I have done wrong?
Here is the code for the Bezier and its Controller objects.
class Controller : public QGraphicsEllipseItem {
public:
Controller(Bezier *bezier);
private:
Bezier *m_bezier;
QVariant itemChange(GraphicsItemChange change, const QVariant
&value);
};
class Bezier : public QGraphicsItem {
public:
Bezier(QPointF pA, QPointF pB, QPointF cA, QPointF cB,
QGraphicsItem *parent = 0, QGraphicsScene *scene = 0);
QRectF boundingRect() const;
QPainterPath shape() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem
*option, QWidget *widget = 0);
Controller *endA;
Controller *endB;
Controller *controlA;
Controller *controlB;
void updateCurve();
private:
QPointF m_pA;
QPointF m_pB;
QPointF m_cA;
QPointF m_cB;
};
Bezier::Bezier(QPointF pA, QPointF pB, QPointF cA, QPointF cB, QGraphicsItem
*parent, QGraphicsScene *scene)
: QGraphicsItem(parent, scene), m_pA(pA), m_pB(pB),
m_cA(cA), m_cB(cB) {
endA = new Controller(this); // constructs a
mouse-moveable 'hot spot' for end A of bezier curve
endB = new Controller(this); // constructs a
mouse-moveable 'hot spot' for end B of bezier curve
controlA = new Controller(this); // constructs a mouse-moveable
'hot spot' for endA control point
controlB = new Controller(this); // constructs a mouse-moveable
'hot spot' for endB control point
// The following initialisation method does not work
// m_pA, m_pB, m_cA, and m_cB are all initialised wrongly (0,0)
// endA position is initialised correctly, but the other
Controllers are wrongly located at 0, 0
/* endA->setPos(m_pA);
endB->setPos(m_pB);
controlA->setPos(m_cA);
controlB->setPos(m_cB);
*/
// The following initialisation method works OK
// m_pA, m_pB, m_cA, and m_cB are all initialised ok
// endA, endB, controlA & controlB are all positioned OK
endA->setPos(pA);
endB->setPos(pB);
controlA->setPos(cA);
controlB->setPos(cB);
}
QRectF Bezier::boundingRect() const {
return shape().controlPointRect().normalized();
}
QPainterPath Bezier::shape() const {
QPainterPath bezpath;
bezpath.moveTo(m_pA);
bezpath.cubicTo(m_cA, m_cB, m_pB);
return bezpath;
}
void Bezier::updateCurve() { // initiate redrawing of
bezier based on new location of Controller objects
prepareGeometryChange();
m_pA = endA->pos();
m_pB = endB->pos();
m_cA = controlA->pos();
m_cB = controlB->pos();
}
void Bezier::paint(QPainter *painter, const QStyleOptionGraphicsItem
*option, QWidget *widget) {
painter->drawPath(shape());
}
Controller::Controller(Bezier *bezier) : QGraphicsEllipseItem() {
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setRect(-5, -5, 10, 10);
setParentItem(bezier);
m_bezier = bezier;
}
QVariant Controller::itemChange(GraphicsItemChange change, const QVariant
&value) {
if (change == QGraphicsItem::ItemPositionChange) {
m_bezier->updateCurve();
}
return value;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20101118/09496933/attachment.html
More information about the Qt-interest-old
mailing list