0
votes

after spend hour's searching for a solution, to build a grid that dynamic adds and removes buttons it doesn't remove the previus ones when going to the next page.

I have search here, and found "some" solutions but they aren't working.

This is my code.

This is the code to fill a vector with myQpushButtons ( added 3 method that I needed on the button )

QString famId = ui->comboBox->itemData(index).toString();
if (vectButtons.size() > 0)
{
    vectButtons.clear();
}
int totalPerPage = gridRow * gridColl;
int countPage = 0;
int totalButtons = 0;
double counterProd = 1.0;
qDebug() << idbConnect.get_Familia(famId)->get_FamProd()->count();
for (pair<QString, Produto> prod : idbConnect.get_Familia(famId)->get_FamProd()->toStdMap())
{
    if (counterProd == totalPerPage)
    {
        countPage++;
        counterProd = 2.0;
        buttons = new myQPushButton();
        buttons->setText("Proximo");
        buttons->set_Tipo(1);
        buttons->set_Pagina((totalPerPage * countPage));
        connect(buttons,SIGNAL(released()),this,SLOT(handleButton()));
        vectButtons.push_back(buttons);
        // #####################################################
        buttons = new myQPushButton();
        buttons->setText("Anterior");
        buttons->set_Tipo(1);
        buttons->set_Pagina((totalPerPage * (countPage - 1)));
        connect(buttons,SIGNAL(released()),this,SLOT(handleButton()));
        vectButtons.push_back(buttons);
        // #####################################################
    }
    buttons = new myQPushButton();
    buttons->setText(prod.second.get_Nome());
    buttons->set_id_Prod(prod.first);
    buttons->set_Tipo(0);
    connect(buttons,SIGNAL(released()),this,SLOT(handleButton()));
    vectButtons.push_back(buttons);
    counterProd++;
    totalButtons++;
}
fillGrid(0);

This is the method to fill the grid, and then add to the layout of thw widget

void MainWindow::fillGrid(int start)
{
grid = new QGridLayout;
for (int i = 0; i < gridRow; i++)
{
    for (int y = 0; y < gridColl; y++)
    {
        grid->addWidget(vectButtons.at(start),i,y);
        start++;
    }
}
ui->widget->setLayout(grid);
ui->widget->repaint();
ui->widget->show();
}

And this one it is called when I click next or previus, to fill the grid with new buttons.

void MainWindow::replaceGrid(int start)
{
/*QLayout *temp;
temp = ui->widget->layout();
temp->deleteLater();
delete temp;
grid->deleteLater();
delete grid;
ui->widget->layout()->deleteLater();
delete ui->widget->layout();*/
removeLayout(ui->widget);
ui->widget->layout()->deleteLater();
delete ui->widget->layout();
grid = new QGridLayout;
for (int i = 0; i < gridRow; i++)
{
    for (int y = 0; y < gridColl; y++)
    {
        if (start < vectButtons.size())
        {
            grid->addWidget(vectButtons.at(start),i,y);
            start++;
        }
    }
}
ui->widget->setLayout(grid);
ui->widget->repaint();
ui->widget->show();
}

This one calls other method, to remove all items from the layout ( in this case a grid ) from the widget, since I saw this solution on this site, saying that we need to remove all items before deleting the layout of an widget.

void MainWindow::removeLayout(QWidget* widget)
{
QLayout* layout = widget->layout();
if (layout != 0)
{
    QLayoutItem *item;
    while ((item = layout->takeAt(0)) != 0)
    {
        layout->removeItem(item);
    }
    delete layout;
}
}

But this doesn't work, when I click next ( to remove all previus buttons and add new ones from the vector ) it will have them on beyend the new buttons don't know why, if I'm removing them and deleting the layout and adding a new one.

Any thought's on this?

1

1 Answers

2
votes

You remove the items from the layout, but you don't delete the buttons. If you want to get rid of the buttons completely, you will have to delete them as well. Or you can just hide them, if you don't want to delete them (you can just do this, no point removing them from the layout if you do this, is there?). Otherwise they will be visible inside their parent widget. You can use QLayoutItem::widget to get the widget.

Maybe a better solution for you is to use QStackedLayout. Here is an example from the docs:

QWidget *firstPageWidget = new QWidget;
QWidget *secondPageWidget = new QWidget;
QWidget *thirdPageWidget = new QWidget;

QStackedLayout *stackedLayout = new QStackedLayout;
stackedLayout->addWidget(firstPageWidget);
stackedLayout->addWidget(secondPageWidget);
stackedLayout->addWidget(thirdPageWidget);

QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(stackedLayout);
setLayout(mainLayout);

And to change the page of the stackedlayout using a QComboBox:

QComboBox *pageComboBox = new QComboBox;
pageComboBox->addItem(tr("Page 1"));
pageComboBox->addItem(tr("Page 2"));
pageComboBox->addItem(tr("Page 3"));
connect(pageComboBox, SIGNAL(activated(int)),
        stackedLayout, SLOT(setCurrentIndex(int)));

If you really need to remove the buttons from the layout, here is a small example how to do it:

centralWidget()->setLayout(new QVBoxLayout);
for(int i = 0; i < 10; i++)
{
    centralWidget()->layout()->addWidget(new QLabel(QString("LABEL%1").arg(i)));
}
QLayoutItem *item;
while((item= centralWidget()->layout()->takeAt(0)) != 0)
{
//        item->widget()->setHidden(true);
    item->widget()->setParent(0); // you can use this or setHidden... up to you
    delete item;
}