I want to parse the QGraphicsGridLayout, but getting this error. The thing is I was able to add QGraphicsProxyWidget as an item but not able to retrieve it. I want to know how to convert a QGraphicsLayoutItem* to QGraphicsProxyWidget* in this line of mainwindow.cpp code auto *currentWidget = static_cast<QGraphicsProxyWidget*>(layout->itemAt(row, col));. When using this static_cast is returning a NULL pointer please help.

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsGridLayout>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    QVector<QString> node_vector = {"abc", "def", "ghi", "jkl"};

    QGraphicsGridLayout *layout;
    QGraphicsView *view;
    QGraphicsScene *scene;

public slots:
    void builGridlayout ();
    void updateGridlaout ();

private:
    Ui::MainWindow *ui;
    QPushButton *updateGridlayout;
    QWidget *menu;
};
#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QGridLayout>
#include <QLabel>
#include <QGraphicsWidget>
#include <QGraphicsProxyWidget>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /* building the gridLayout when creating the QMainWindow */
    builGridlayout();

    menu = new QWidget;
    QHBoxLayout *menuLayout = new QHBoxLayout(menu);
    menu->setLayout(menuLayout);

    /* creating the button to update GridLayout */
    updateGridlayout = new QPushButton("update gridlayout");
    menuLayout->addWidget(updateGridlayout);
    connect(updateGridlayout, &QPushButton::released, this, &MainWindow::updateGridlaout);

    menuLayout->addStretch();
    this->setMenuWidget(menu);
}

MainWindow::~MainWindow()
{
    delete ui;
}

/* creating a GraphicsGridLayout with QGraphicsProxyWidget */
void MainWindow::builGridlayout()
{
    layout = new QGraphicsGridLayout;
    scene = new QGraphicsScene(this);

    QGraphicsWidget *window = new QGraphicsWidget();

    int numCols = 4,row = 0,col = 0;
    for(int index = 0; index < node_vector.size(); index++){

        QString node = node_vector[index];

        QLabel *label = new QLabel;
        label->setText(node);
        label->setMargin(5);

        /* converting the QLabel into QGraphicsProxyWidget and
         * adding it the QGraphicsGridLayout*/
        QGraphicsProxyWidget *stringLabel = scene->addWidget(label);
        layout->addItem(stringLabel,row+1, col+1);

        col++;
        if(col == numCols) row++;
        col = col % numCols;
    }

    window->setLayout(layout);
    scene->addItem(window);

    view = new QGraphicsView(scene, this);
    setCentralWidget(view);
    view->setGeometry(0, 0, this->maximumWidth(), this->maximumHeight());
    view->show();
}

/* method to update the QGraphicsProxyWidget present in the QGrpahicsGridLayout */
void MainWindow::updateGridlaout()
{
    int itemCount = layout->count();

    int numCols = 4;
    int row = 0, col = 0;
    for (int i = 0; i < itemCount; ++i)
    {
        auto *currentWidget = static_cast<QGraphicsProxyWidget*>(layout->itemAt(row, col));

        if (currentWidget) qDebug() << "successful";
        else qDebug() << "getting nullptr";

        col++;
        if (col == numCols) row++;
        col = col % numCols;
    }
}
1

There are 1 answers

4
scopchanov On

Cause

QGraphicsProxyWidget is a QGraphicsWidget, which in turn is both QGraphicsObject and QGraphicsLayoutItem.

QGraphicsGridLayout::itemAt returns QGraphicsLayoutItem, hence by writing this:

QGraphicsProxyWidget *currentWidget = layout->itemAt(row, col);

the compiler recognizes only the QGraphicsLayoutItem-part of this multiple inheritance and gives you an error.

Solution

Cast layout->itemAt(row, col) explicitly to QGraphicsProxyWidget like this:

auto *currentWidget = static_cast<QGraphicsProxyWidget *>(layout->itemAt(row, col));

Note: You have to be sure, that the item at this position is indeed QGraphicsProxyWidget. If you have some kind of QGraphicsLayout instead, your program will crash.