[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