Search code examples
qt5qpushbuttonqgridlayout

QGridLayout not displaying added widgets


    QWidget* centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);
    QVBoxLayout* mainLayout = new QVBoxLayout(centralWidget);
    topLineLayout = new QHBoxLayout();
    minesCounterLabel = new QLabel();
    emoticonButton = new QPushButton();
    timerLabel = new QLabel("0");
    topLineLayout -> addWidget(minesCounterLabel);
    topLineLayout -> addWidget(emoticonButton);
    topLineLayout -> addWidget(timerLabel);
    mainLayout -> addLayout(topLineLayout);
    paddingLayout = new QGridLayout();
    paddingLayout -> setSpacing(0);
    std::vector <Cell> cellsVector;
    for(int i = 0; i < paddingHeight; i++)
    {
        for(int j = 0; j < paddingWidth; j++)
        {
            Cell* cell = new Cell(&cellsVector, j, i, false);
            cellsVector.push_back(*cell);
        }
    }
    for(int i = 0; i < cellsVector.size(); i++)
    {
        paddingLayout -> addWidget(&cellsVector[i], cellsVector[i].getX(), cellsVector[i].getY());
    }
    mainLayout -> addLayout(paddingLayout);

This is mainwindow.h file and this is an extract of MainWindow class constructor. What I do not understand is why paddingLayout does not show any widgets that are added to it, in this case, the "Cells". Any ideas?

Edit:

Definition of class "Cell" and code for its constructors:

class Cell : public QPushButton
{
    Q_OBJECT

    public:

        Cell(std::vector <Cell> *, int, int, bool, QWidget* parent = 0);
        Cell(const Cell&);
        bool hasMine();
        int getX();
        int getY();
        std::vector <Cell> * getCellsVector();
        void setHasMine(bool);
        ~Cell();
        Cell operator=(const Cell& object)
        {
            this -> cellsVector = object.cellsVector;
            this -> mine = object.mine;
            this -> x = object.x;
            this -> y = object.y;
            setFixedSize(20, 20);
            connect(this, &QPushButton::clicked, this, &Cell::cellClicked);
        }

    private:

        std::vector <Cell> * cellsVector;
        int x;
        int y;
        bool mine;
        // Determine how many mines are around this cell.
        int countMines();
        void cellClicked();
};

Cell::Cell(std::vector <Cell> * cellsVector, int x, int y, bool mine = false, QWidget* parent) : QPushButton(parent)
{
    this -> cellsVector = cellsVector;
    this -> mine = mine;
    this -> x = x;
    this -> y = y;
    setFixedSize(20, 20);
    connect(this, &QPushButton::clicked, this, &Cell::cellClicked);
}

Cell::Cell(const Cell& object)
{
    this -> cellsVector = object.cellsVector;
    this -> mine = object.mine;
    this -> x = object.x;
    this -> y = object.y;
    setFixedSize(20, 20);
    connect(this, &QPushButton::clicked, this, &Cell::cellClicked);
}

If any more code is needed, please say!


Solution

  • First, there is problem with assigment operator of Cell, should be

    Cell& operator=(const Cell& object)
    {
         if (&object == this) return *this;
         this -> cellsVector = object.cellsVector;
         this -> mine = object.mine;
         this -> x = object.x;
         this -> y = object.y;
         setFixedSize(20, 20);
         connect(this, &QPushButton::clicked, this, &Cell::cellClicked);
         return *this; // you must return value
    }
    

    big problem is with std::vector <Cell> cellsVector;, this vector is created, cells are inserted into it, then in this line

    paddingLayout -> addWidget(&cellsVector[i], cellsVector[i].getX(), cellsVector[i].getY());
    

    you take address of cell, and pass it to QGridLayout, but what will happen with cellsVector at the end of function ? This vector is destroyed, and all cells are also destroyed. QGridLayout holds pointers to deleted object.