Search code examples
c++qtqt5qgridlayout

How can i toggle a widget visibility that is in a grid layout?


I want to do a list that changes it's fields numbers when the user changes a the value of a spinbox. Something like this:

First 5 fields by default

Then just 1 field for example

And if the user wants to change it again, he can put 5 fields again.

I made a GridLayout and a couple of QList, one for the Labels and the other one for LineEdits. I did this:

I create a basic case (with just 1 field) and i later add more on excecution time adding Widgets to the GridLayout by:

gridLayout->addWidget(labels.at(x), 0, 1)

where labels is the QList. it works fine to add widgets but i can't remove and add again.

i tried using

gridLayout->removeWidget(lables.at(x), 0, 1)
labels.at(x)->hide()
label.at(x)->setVisible(false)

all works but i can't show it again with none of this:

gridLayout->addWidget(labels.at(x), 0, 1)
labels.at(x)->show()
label.at(x)->setVisible(true)

Solution

  • Layouts are handlers of the geometry of the widgets. If you use the removeWidget() function, you will only remove that element from the layout but it will still be visible. If you want it not to be visible you have to delete it with delete.

    In the following example I show you how to add and remove the widgets using the valueChanged signal of the QSpinBox.

    void Dialog::on_spinBox_valueChanged(int arg1)
    {
    
        int nElements = labels.count();
    
        //add
        if(arg1 > nElements){
            for(int i=nElements; i < arg1; i++){
                QLabel *label = new QLabel(QString::number(i), this);
                QLineEdit *line = new QLineEdit(QString::number(i), this);
                labels.append(label);
                lines.append(line);
                ui->gridLayout->addWidget(label, i, 0, 1, 1);
                ui->gridLayout->addWidget(line, i, 1, 1, 1);
            }
        }
    
        //remove
        else if(arg1 < nElements){
            for(int i=arg1; i < nElements; i++){
                QLabel *label = labels.at(i);
                QLineEdit *line = lines.at(i);
                ui->gridLayout->removeWidget(label);
                ui->gridLayout->removeWidget(line);
                labels.removeAt(i);
                lines.removeAt(i);
                delete label;
                delete line;
            }
        }
    }
    

    Add:

    enter image description here

    Remove:

    enter image description here