QGraphicsScene item is drawn at twice(x2) position

  • In the following code I am creating a custom widget which has a subclass of QGraphicsScene embeded in it. My aim is to click and add a point to the scene. A point is my subclass of QGraphicsItem. I want to move that point around and later connect it to other points and make a spline path. The problem I am facing is that the point is not drawn at where I click but at a place which is form by doubling the mouse-event's scenePos() coordinates. So if I click at (100,100) the point is drawn at (200,200). I suspect that I have misunderstood the coordinate system despite reading the documentation. So I am asking additionally to point me to some simple-to-digest advice on how the widgets placement works. My example code follows:

    /* use the following pro:
    QT += widgets core gui
    CONFIG += debug console
    SOURCES = example.cpp
    TARGET = example
    #include <QGraphicsItem>
    #include <QPainter>
    #include <QWidget>
    #include <QRectF>
    #include <QPointF>
    #include <QGraphicsScene>
    #include <QStyleOptionGraphicsItem>
    #include <QGraphicsSceneMouseEvent>
    #include <QKeyEvent>
    #include <QGraphicsView>
    #include <QApplication>
    #include <QOpenGLWidget>
    #include <QMainWindow>
    #include <QGridLayout>
    #include <QDebug>
    class GIPoint : public QGraphicsItem{
    	GIPoint(QGraphicsItem * parent, const QPointF &position);
    	QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
    	QRectF boundingRect() const override;
    	void paint(
    		QPainter *painter,
    		const QStyleOptionGraphicsItem *option,
    		QWidget *widget
    class GraphicsSceneWidget : public QGraphicsScene {
    	explicit GraphicsSceneWidget(QObject *parent);
    	virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
    class VectorGraphicsWidget : public QWidget {
    	VectorGraphicsWidget(QWidget *parent);
    	GraphicsSceneWidget *myGraphicsSceneWidget;
    // implementation
    	QGraphicsItem *parent,
    	const QPointF &position
    ) : QGraphicsItem(parent) {
    	setFlag(QGraphicsItem::ItemIsMovable, true);
    	setFlag(QGraphicsItem::ItemIsSelectable, true);
    	qWarning() << "GIPoint::GIPoint() : init at " << position;
    QVariant GIPoint::itemChange(
    	GraphicsItemChange change,
    	const QVariant &value
    	if (change == QGraphicsItem::ItemPositionChange) {
    		qWarning("position changed");
    	return value;
    QRectF GIPoint::boundingRect() const {
    	return QRectF(pos().x(), pos().y(), 5, 5);
    //	return QRectF(0,0, 5, 5);
    void GIPoint::paint(
    	QPainter *painter,
    	const QStyleOptionGraphicsItem *option,
    	QWidget *widget
    	(void )option;
    	(void )widget;
    	QPointF xx = scenePos();
    	QRectF rect = QRectF(xx.x(), xx.y(), 10, 10);
    	qWarning() << "painting: scenePos " << scenePos() << ", rect " << rect;
    	QBrush brush = QBrush(Qt::black, Qt::SolidPattern);
    	//painter->fillRect(rect, brush);
    GraphicsSceneWidget::GraphicsSceneWidget(QObject *parent)
    	: QGraphicsScene(parent)
    void GraphicsSceneWidget::mousePressEvent(
    	QGraphicsSceneMouseEvent *event
    	GIPoint *gip = new GIPoint(Q_NULLPTR, event->scenePos());
    VectorGraphicsWidget::VectorGraphicsWidget(QWidget *parent) :
    	myGraphicsSceneWidget = new GraphicsSceneWidget(this);
    	QGraphicsView *view = new QGraphicsView(myGraphicsSceneWidget);
    	myGraphicsSceneWidget->setSceneRect(QRectF(0, 0, 500, 500));
    	QGridLayout *centralLayout = new QGridLayout;
    		QRectF(0, 0, 100, 100),
    VectorGraphicsWidget::~VectorGraphicsWidget() {
    	delete myGraphicsSceneWidget;
    int main(int argc, char **argv){
    	QApplication app(argc, argv);
    	QMainWindow *w = new QMainWindow();
    	w->resize(500, 500);
    	w->setCentralWidget(new VectorGraphicsWidget(Q_NULLPTR));
    	return app.exec();

  • I have just figured it out.

    My first misunderstanding was that the boundingRect()'s coordinates must be (-0.5,-0.5) which means they are relative to the current item's position and not absolute on the Scene. and so this is the correct one:

    QRectF GIPoint::boundingRect() const {
    //	return QRectF(pos().x(), pos().y(), 5, 5);
    	return QRectF(-0.5, -0.5, 5, 5);

    My second misunderstanding was in paint(). Do not use the pos() or scenePos() coordinates in order to draw the item. Instead draw it at (0,0). So the corrected paint() is this:

    void GIPoint::paint(
            QPainter *painter,
            const QStyleOptionGraphicsItem *option,
            QWidget *widget
            (void )option;
            (void )widget;
            QRectF rect = boundingRect();
            qWarning() << "painting: scenePos " << scenePos() << ", rect " << rect;
            QBrush brush = QBrush(Qt::black, Qt::SolidPattern);
            painter->fillRect(rect, brush);  

    The original program in my question still needs to be modified. Or shall I edit the changes in?

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.