Minee
Minee

Reputation: 478

QGraphicsItem::pos returns 0 when in layout

I have the following Qt code fragment in my widget.cpp:

Widget::Widget(QWidget *parent)
: QWidget(parent)
{
    m_Scene = new QGraphicsScene(this);
    m_Scene->setSceneRect(0, 0, 1024, 768);

    GraphicsTextItem* m_1 = new GraphicsTextItem(nullptr, QString("l_1"));

    GraphicsTextItem* m_2 = new GraphicsTextItem(nullptr, QString("l_2"));


    QGraphicsLinearLayout* layout = new QGraphicsLinearLayout;
    layout->addItem(m_1);
    layout->addItem(m_2);

    QGraphicsWidget* list = new QGraphicsWidget;
    list->setLayout(layout);
    m_Scene->addItem(list);

    qDebug() << m_2->x() << " " << m_2->y(); // Prints 0,0 Why?

    QGraphicsView* view = new QGraphicsView(this);
    view->setScene(m_Scene);
}

GraphicsTextItem is a derived class of QGraphicsWidget :

class GraphicsTextItem : public QGraphicsWidget
{
private:
    QString m_Name;
public:
    GraphicsTextItem(QGraphicsItem * parent = nullptr, const QString& name = QString());
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
    {
        QFont font("Times", 12);
        painter->setFont(font);
        painter->drawText(0, 0, m_Name);
    }
};

I also give my short main located in main.cpp:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

My question is that why the qDebug line prinnts me 0,0 as certainly the position of the widget is non-zero. If I don't put the widget in a layout and I call setPos() qDebug prints the correct value set previously.

Upvotes: 2

Views: 405

Answers (1)

eyllanesc
eyllanesc

Reputation: 243887

The initial position of all QGraphicsItem is (0, 0) and that includes m_2, and m_2 will change its position when the QGraphicsLinearLayout is applied that will be an instant after the synchronous task is finished and the eventloop starts working, this can be observed using QTimer::singleShot(0, ...):

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{

    m_Scene = new QGraphicsScene(this);
    QGraphicsView* view = new QGraphicsView(this);
    view->setScene(m_Scene);

    m_Scene->setSceneRect(0, 0, 1024, 768);

    GraphicsTextItem *m_1 = new GraphicsTextItem(nullptr, QString("l_1"));

    GraphicsTextItem *m_2 = new GraphicsTextItem(nullptr, QString("l_2"));


    QGraphicsLinearLayout* layout = new QGraphicsLinearLayout;
    layout->addItem(m_1);
    layout->addItem(m_2);

    QGraphicsWidget* list = new QGraphicsWidget;
    list->setLayout(layout);
    m_Scene->addItem(list);

    qDebug() << "synchronous" << m_2->pos() << m_2->mapToScene(QPointF{});

    QTimer::singleShot(0, m_2, [m_2](){
        qDebug() << "asynchronous"<< m_2->pos() << m_2->mapToScene(QPointF{});
    });
}

Output:

synchronous QPointF(0,0) QPointF(0,0)
asynchronous QPointF(62,6) QPointF(62,6)

Upvotes: 3

Related Questions